gramps/src/gramps_main.py

1929 lines
73 KiB
Python
Raw Normal View History

2002-10-20 19:55:16 +05:30
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2004 Donald N. Allingham
2002-10-20 19:55:16 +05:30
#
# 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$
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# Standard python modules
#
#-------------------------------------------------------------------------
import os
#-------------------------------------------------------------------------
#
# internationalization
#
#-------------------------------------------------------------------------
2003-08-17 07:44:33 +05:30
from gettext import gettext as _
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
import gobject
import gtk
import gnome
2002-10-20 19:55:16 +05:30
import gnome.ui
import gtk.glade
import gtk.gdk
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# gramps modules
#
#-------------------------------------------------------------------------
2003-01-12 10:52:21 +05:30
import RelLib
import PedView
import MediaView
import PlaceView
import FamilyView
import SourceView
import PeopleView
import GenericFilter
import GrampsMime
2002-10-20 19:55:16 +05:30
import DisplayTrace
import const
import Plugins
import Utils
import Bookmarks
import GrampsCfg
import EditPerson
import Find
2004-04-10 09:08:48 +05:30
import DbPrompter
import TipOfDay
import ArgHandler
2004-04-10 09:08:48 +05:30
from QuestionDialog import *
try: # First try python2.3 and later: this is the future
2004-04-10 09:08:48 +05:30
from bsddb import db
except ImportError: # try python2.2
2004-04-10 09:08:48 +05:30
from bsddb3 import db
2002-10-20 19:55:16 +05:30
2002-12-29 11:14:35 +05:30
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
_HOMEPAGE = "http://gramps.sourceforge.net"
_MAILLIST = "http://sourceforge.net/mail/?group_id=25770"
_BUGREPORT = "http://sourceforge.net/tracker/?group_id=25770&atid=385137"
PERSON_VIEW = 0
FAMILY_VIEW1 = 1
FAMILY_VIEW2 = 2
PEDIGREE_VIEW = 3
SOURCE_VIEW = 4
PLACE_VIEW = 5
MEDIA_VIEW = 6
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# Main GRAMPS class
#
#-------------------------------------------------------------------------
class Gramps:
2003-05-17 09:44:13 +05:30
def __init__(self,args):
2002-10-20 19:55:16 +05:30
try:
self.program = gnome.program_init('gramps',const.version,
gnome.libgnome_module_info_get(),
args, const.popt_table)
except:
self.program = gnome.program_init('gramps',const.version)
2003-03-31 07:03:40 +05:30
self.program.set_property('app-libdir','%s/lib' % const.prefixdir)
self.program.set_property('app-datadir','%s/share/gramps' % const.prefixdir)
self.program.set_property('app-sysconfdir','%s/etc' % const.prefixdir)
self.program.set_property('app-prefix', const.prefixdir)
2002-10-20 19:55:16 +05:30
self.parents_index = 0
self.active_person = None
self.bookmarks = None
self.c_details = 6
self.cl = 0
2002-10-20 19:55:16 +05:30
self.history = []
self.mhistory = []
self.hindex = -1
2003-01-12 10:52:21 +05:30
self.db = RelLib.GrampsDB()
2002-10-20 19:55:16 +05:30
self.db.set_iprefix(GrampsCfg.iprefix)
self.db.set_oprefix(GrampsCfg.oprefix)
self.db.set_fprefix(GrampsCfg.fprefix)
self.db.set_sprefix(GrampsCfg.sprefix)
self.db.set_pprefix(GrampsCfg.pprefix)
GrampsCfg.loadConfig(self.pref_callback)
if GrampsCfg.get_bool('/apps/gramps/betawarn') == 0:
WarningDialog(_("Use at your own risk"),
_("This is an unstable development version of GRAMPS. "
"It is intended as a technology preview. Do not trust your "
"family database to this development version. This version may "
"contain bugs which could corrupt your database."))
GrampsCfg.set_bool('/apps/gramps/betawarn',1)
self.RelClass = Plugins.relationship_class
self.relationship = self.RelClass(self.db)
self.gtop = gtk.glade.XML(const.gladeFile, "gramps", "gramps")
2002-10-20 19:55:16 +05:30
self.init_interface()
ArgHandler.ArgHandler(self,args)
# Don't show main window until ArgHandler is done.
2004-06-22 04:54:51 +05:30
# This prevents a window from annoyingly popping up when
# the command line args are sufficient to operate without it.
self.topWindow.show()
if GrampsCfg.usetips:
TipOfDay.TipOfDay()
self.db.set_researcher(GrampsCfg.get_researcher())
2002-10-20 19:55:16 +05:30
def pref_callback(self,val):
self.modify_statusbar()
self.family_view.init_interface()
self.update_display(1)
self.goto_active_person()
self.toolbar.set_style(GrampsCfg.toolbar)
2002-10-20 19:55:16 +05:30
def init_interface(self):
"""Initializes the GLADE interface, and gets references to the
widgets that it will need.
"""
self.topWindow = self.gtop.get_widget("gramps")
2002-10-20 19:55:16 +05:30
self.report_button = self.gtop.get_widget("reports")
self.tool_button = self.gtop.get_widget("tools")
self.remove_button = self.gtop.get_widget("removebtn")
self.edit_button = self.gtop.get_widget("editbtn")
self.remove_item = self.gtop.get_widget("remove_item")
self.edit_item = self.gtop.get_widget("edit_item")
2002-10-20 19:55:16 +05:30
self.sidebar = self.gtop.get_widget('side_event')
self.filterbar = self.gtop.get_widget('filterbar')
self.tool_button.set_sensitive(0)
self.report_button.set_sensitive(0)
self.remove_button.set_sensitive(0)
self.edit_button.set_sensitive(0)
self.remove_item.set_sensitive(0)
self.edit_item.set_sensitive(0)
2002-10-20 19:55:16 +05:30
set_panel(self.sidebar)
set_panel(self.gtop.get_widget('side_people'))
set_panel(self.gtop.get_widget('side_family'))
set_panel(self.gtop.get_widget('side_pedigree'))
set_panel(self.gtop.get_widget('side_sources'))
set_panel(self.gtop.get_widget('side_places'))
set_panel(self.gtop.get_widget('side_media'))
self.sidebar_btn = self.gtop.get_widget("sidebar1")
self.filter_btn = self.gtop.get_widget("filter1")
self.toolbar_btn = self.gtop.get_widget("toolbar2")
2002-10-20 19:55:16 +05:30
self.statusbar = self.gtop.get_widget("statusbar")
2002-10-20 19:55:16 +05:30
self.filter_list = self.gtop.get_widget("filter_list")
self.views = self.gtop.get_widget("views")
2002-10-20 19:55:16 +05:30
self.merge_button= self.gtop.get_widget("merge")
self.canvas = self.gtop.get_widget("canvas1")
self.toolbar = self.gtop.get_widget("toolbar1")
self.toolbardock = self.gtop.get_widget("dockitem2")
2002-10-20 19:55:16 +05:30
self.filter_text = self.gtop.get_widget('filter')
self.qual_label = self.gtop.get_widget("qual")
self.child_type = self.gtop.get_widget("childtype")
self.spouse_tab = self.gtop.get_widget("lab_or_list")
self.pref_spouse = self.gtop.get_widget("pref_spouse")
self.multi_spouse= self.gtop.get_widget("multi_spouse")
self.spouse_pref = self.gtop.get_widget("prefrel")
self.spouse_edit = self.gtop.get_widget("edit_sp")
self.spouse_del = self.gtop.get_widget("delete_sp")
self.spouse_combo= self.gtop.get_widget("spouse_combo")
self.spouse_tab = self.gtop.get_widget("spouse_tab")
2004-05-19 11:43:36 +05:30
self.undolabel = self.gtop.get_widget('undolabel')
self.redolabel = self.gtop.get_widget('redolabel')
2002-10-20 19:55:16 +05:30
2004-05-19 11:43:36 +05:30
self.db.set_undo_label(self.undolabel)
self.db.set_redo_label(self.redolabel)
2002-10-20 19:55:16 +05:30
self.use_sidebar = GrampsCfg.get_view()
self.sidebar_btn.set_active(self.use_sidebar)
self.use_filter = GrampsCfg.get_filter()
self.filter_btn.set_active(self.use_filter)
self.use_toolbar = GrampsCfg.get_toolbar_on()
self.toolbar_btn.set_active(self.use_toolbar)
self.child_model = gtk.ListStore(
gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING,
gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING,
gobject.TYPE_STRING,
)
2002-10-20 19:55:16 +05:30
self.build_plugin_menus()
self.init_filters()
self.toolbar.set_style(GrampsCfg.toolbar)
2003-03-27 08:46:09 +05:30
self.views.set_show_tabs(0)
2002-10-20 19:55:16 +05:30
2003-01-12 10:52:21 +05:30
self.family_view = FamilyView.FamilyView(self)
self.people_view = PeopleView.PeopleView(self)
self.pedigree_view = PedView.PedigreeView(self,
self.canvas, self.modify_statusbar, self.statusbar,
self.change_active_person, self.load_person
)
self.place_view = PlaceView.PlaceView(self,self.db,self.gtop,
self.update_display)
self.source_view = SourceView.SourceView(self,self.db,self.gtop,
self.update_display)
self.media_view = MediaView.MediaView(self,self.db,self.gtop,
self.update_display)
2002-10-20 19:55:16 +05:30
self.add_button = self.gtop.get_widget('addbtn')
self.add_item = self.gtop.get_widget('add_item')
self.backbtn = self.gtop.get_widget('back_btn')
self.fwdbtn = self.gtop.get_widget('fwd_btn')
self.gomenuitem = self.gtop.get_widget("go1")
2002-10-20 19:55:16 +05:30
self.wins = self.gtop.get_widget("windows1")
self.wins.set_submenu(gtk.Menu())
self.winsmenu = self.wins.get_submenu()
2004-02-25 08:50:53 +05:30
self.child_windows = {}
2002-10-20 19:55:16 +05:30
self.gtop.signal_autoconnect({
"on_undo_activate" : self.undo,
"on_column_order_activate": self.column_order,
"on_back_clicked" : self.back_clicked,
"on_back_pressed" : self.back_pressed,
"on_fwd_clicked" : self.fwd_clicked,
"on_fwd_pressed" : self.fwd_pressed,
2002-10-20 19:55:16 +05:30
"on_editbtn_clicked" : self.edit_button_clicked,
"on_addbtn_clicked" : self.add_button_clicked,
"on_removebtn_clicked" : self.remove_button_clicked,
"delete_event" : self.delete_event,
2003-03-31 07:03:40 +05:30
"destroy_passed_object" : Utils.destroy_passed_object,
"on_about_activate" : self.on_about_activate,
"on_add_bookmark_activate" : self.on_add_bookmark_activate,
"on_add_place_clicked" : self.place_view.on_add_place_clicked,
"on_add_source_clicked" : self.source_view.on_add_clicked,
"on_addperson_clicked" : self.load_new_person,
"on_apply_filter_clicked" : self.on_apply_filter_clicked,
"on_arrow_left_clicked" : self.pedigree_view.on_show_child_menu,
"on_canvas1_event" : self.pedigree_view.on_canvas1_event,
"on_contents_activate" : self.on_contents_activate,
"on_faq_activate" : self.on_faq_activate,
2003-03-31 07:03:40 +05:30
"on_default_person_activate" : self.on_default_person_activate,
"on_delete_person_clicked" : self.delete_person_clicked,
"on_delete_place_clicked" : self.place_view.on_delete_clicked,
"on_delete_source_clicked" : self.source_view.on_delete_clicked,
"on_delete_media_clicked" : self.media_view.on_delete_clicked,
"on_edit_active_person" : self.load_active_person,
"on_edit_selected_people" : self.load_selected_people,
"on_edit_bookmarks_activate" : self.on_edit_bookmarks_activate,
"on_exit_activate" : self.on_exit_activate,
"on_family_activate" : self.on_family_activate,
2003-03-31 07:03:40 +05:30
"on_family1_activate" : self.on_family1_activate,
"on_family2_activate" : self.on_family2_activate,
2003-03-31 07:03:40 +05:30
"on_find_activate" : self.on_find_activate,
"on_findname_activate" : self.on_findname_activate,
"on_home_clicked" : self.on_home_clicked,
"on_new_clicked" : self.on_new_clicked,
"on_notebook1_switch_page" : self.on_views_switch_page,
"on_ok_button1_clicked" : self.on_ok_button1_clicked,
"on_open_activate" : self.on_open_activate,
"on_import_activate" : self.on_import_activate,
"on_export_activate" : self.on_export_activate,
2003-03-31 07:03:40 +05:30
"on_pedigree1_activate" : self.on_pedigree1_activate,
"on_person_list1_activate" : self.on_person_list1_activate,
"on_main_key_release_event" : self.on_main_key_release_event,
"on_media_activate" : self.on_media_activate,
"on_media_list_select_row" : self.media_view.on_select_row,
"on_media_list_drag_data_get" : self.media_view.on_drag_data_get,
"on_media_list_drag_data_received" : self.media_view.on_drag_data_received,
"on_merge_activate" : self.on_merge_activate,
"on_sidebar1_activate" : self.on_sidebar_activate,
"on_toolbar2_activate" : self.on_toolbar_activate,
2003-03-31 07:03:40 +05:30
"on_filter1_activate" : self.on_filter_activate,
"on_places_activate" : self.on_places_activate,
"on_preferences1_activate" : self.on_preferences_activate,
"on_reports_clicked" : self.on_reports_clicked,
"on_revert_activate" : self.on_revert_activate,
"on_show_plugin_status" : self.on_show_plugin_status,
"on_source_list_button_press" : self.source_view.button_press,
"on_sources_activate" : self.on_sources_activate,
"on_tools_clicked" : self.on_tools_clicked,
"on_gramps_home_page_activate" : self.home_page_activate,
"on_gramps_report_bug_activate" : self.report_bug_activate,
"on_gramps_mailing_lists_activate" : self.mailing_lists_activate,
"on_open_example" : self.open_example,
2004-06-22 04:54:51 +05:30
})
2002-10-20 19:55:16 +05:30
2002-10-20 19:55:16 +05:30
self.enable_filter(self.use_filter)
2003-03-27 08:46:09 +05:30
self.enable_sidebar(self.use_sidebar)
self.find_place = None
self.find_person = None
self.find_source = None
self.find_media = None
if GrampsCfg.defaultview == 0:
self.views.set_current_page(PERSON_VIEW)
elif GrampsCfg.familyview == 0:
self.views.set_current_page(FAMILY_VIEW1)
else:
self.views.set_current_page(FAMILY_VIEW2)
self.accel_group = gtk.AccelGroup()
self.topWindow.add_accel_group(self.accel_group)
self.back = gtk.ImageMenuItem(gtk.STOCK_GO_BACK)
self.forward = gtk.ImageMenuItem(gtk.STOCK_GO_FORWARD)
self.enable_toolbar(self.use_toolbar)
def undo(self,*args):
self.db.undo()
if self.active_person:
p = self.db.try_to_find_person_from_id(self.active_person.get_id())
self.change_active_person(p)
self.place_view.change_db(self.db)
self.people_view.change_db(self.db)
2004-05-14 05:18:40 +05:30
self.people_view.apply_filter()
self.source_view.change_db(self.db)
self.media_view.change_db(self.db)
self.family_view.load_family()
def set_column_order(self,list):
self.db.set_column_order(list)
self.people_view.build_columns()
def set_place_column_order(self,list):
self.db.set_place_column_order(list)
self.place_view.build_columns()
def set_source_column_order(self,list):
self.db.set_source_column_order(list)
self.source_view.build_columns()
def set_media_column_order(self,list):
self.db.set_media_column_order(list)
self.media_view.build_columns()
def column_order(self,obj):
import ColumnOrder
cpage = self.views.get_current_page()
if cpage == PERSON_VIEW:
ColumnOrder.ColumnOrder(self.db.get_column_order(),
PeopleView.column_names,
self.set_column_order)
elif cpage == SOURCE_VIEW:
ColumnOrder.ColumnOrder(self.db.get_source_column_order(),
SourceView.column_names,
self.set_source_column_order)
elif cpage == PLACE_VIEW:
ColumnOrder.ColumnOrder(self.db.get_place_column_order(),
PlaceView.column_names,
self.set_place_column_order)
elif cpage == MEDIA_VIEW:
ColumnOrder.ColumnOrder(self.db.get_media_column_order(),
MediaView.column_names,
self.set_media_column_order)
def clear_history(self):
self.history = []
self.mhistory = []
self.hindex = -1
self.back.set_sensitive(0)
self.forward.set_sensitive(0)
self.backbtn.set_sensitive(0)
self.fwdbtn.set_sensitive(0)
self.redraw_histmenu()
def redraw_histmenu(self):
"""Create the history submenu of the Go menu"""
# Start a brand new menu and create static items:
# back, forward, separator, home.
gomenu = gtk.Menu()
self.back.destroy()
self.forward.destroy()
self.back = gtk.ImageMenuItem(gtk.STOCK_GO_BACK)
self.back.connect("activate",self.back_clicked)
self.back.add_accelerator("activate", self.accel_group,
gtk.gdk.keyval_from_name("Left"),
gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE)
self.back.show()
gomenu.append(self.back)
self.forward = gtk.ImageMenuItem(gtk.STOCK_GO_FORWARD)
self.forward.connect("activate",self.fwd_clicked)
self.forward.add_accelerator("activate", self.accel_group,
gtk.gdk.keyval_from_name("Right"),
gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE)
self.forward.show()
gomenu.append(self.forward)
item = gtk.MenuItem()
item.show()
gomenu.append(item)
#FIXME: revert to stock item when German gtk translation is fixed
#item = gtk.ImageMenuItem(gtk.STOCK_HOME)
item = gtk.ImageMenuItem(_("Home"))
2004-06-22 04:54:51 +05:30
im = gtk.image_new_from_stock(gtk.STOCK_HOME,gtk.ICON_SIZE_MENU)
im.show()
item.set_image(im)
item.connect("activate",self.on_home_clicked)
item.add_accelerator("activate", self.accel_group,
gtk.gdk.keyval_from_name("Home"),
gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE)
item.show()
gomenu.append(item)
try:
if len(self.history) > 0:
# Draw separator
item = gtk.MenuItem()
item.show()
gomenu.append(item)
pids = self.mhistory[:]
pids.reverse()
num = 0
haveit = []
for pid in pids:
if num >= 10:
break
if pid not in haveit:
haveit.append(pid)
person = self.db.get_person(pid)
item = gtk.MenuItem("_%d. %s [%s]" %
(num,person.get_primary_name().get_name(),pid))
item.connect("activate",self.bookmark_callback,person.get_id())
item.show()
gomenu.append(item)
num = num + 1
else:
self.back.set_sensitive(0)
self.forward.set_sensitive(0)
except:
self.clear_history()
self.gomenuitem.remove_submenu()
self.gomenuitem.set_submenu(gomenu)
def build_backhistmenu(self,event):
"""Builds and displays the menu with the back portion of the history"""
if self.hindex > 0:
backhistmenu = gtk.Menu()
backhistmenu.set_title(_('Back Menu'))
pids = self.history[:self.hindex]
pids.reverse()
num = 1
for pid in pids:
if num <= 10:
f,r = divmod(num,10)
hotkey = "_%d" % r
elif num <= 20:
hotkey = "_%s" % chr(ord('a')+num-11)
elif num >= 21:
break
person = self.db.try_to_find_person_from_id(pid)
item = gtk.MenuItem("%s. %s [%s]" %
(hotkey,person.get_primary_name().get_name(),pid))
item.connect("activate",self.back_clicked,num)
item.show()
backhistmenu.append(item)
num = num + 1
backhistmenu.popup(None,None,None,event.button,event.time)
def back_pressed(self,obj,event):
if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
self.build_backhistmenu(event)
def build_fwdhistmenu(self,event):
"""Builds and displays the menu with the forward portion of the history"""
if self.hindex < len(self.history)-1:
fwdhistmenu = gtk.Menu()
fwdhistmenu.set_title(_('Forward Menu'))
pids = self.history[self.hindex+1:]
num = 1
for pid in pids:
if num <= 10:
f,r = divmod(num,10)
hotkey = "_%d" % r
elif num <= 20:
hotkey = "_%s" % chr(ord('a')+num-11)
elif num >= 21:
break
person = self.db.get_person(pid)
item = gtk.MenuItem("%s. %s [%s]" %
(hotkey,person.get_primary_name().get_name(),pid))
item.connect("activate",self.fwd_clicked,num)
item.show()
fwdhistmenu.append(item)
num = num + 1
fwdhistmenu.popup(None,None,None,event.button,event.time)
def fwd_pressed(self,obj,event):
if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
self.build_fwdhistmenu(event)
def set_buttons(self,val):
self.report_menu.set_sensitive(val)
self.tools_menu.set_sensitive(val)
self.report_button.set_sensitive(val)
self.tool_button.set_sensitive(val)
if self.views.get_current_page() == PERSON_VIEW:
self.remove_button.set_sensitive(val)
self.edit_button.set_sensitive(val)
self.remove_item.set_sensitive(val)
self.edit_item.set_sensitive(val)
def back_clicked(self,obj,step=1):
if self.hindex > 0:
try:
self.hindex -= step
self.active_person = self.db.get_person(self.history[self.hindex])
self.modify_statusbar()
self.update_display(0)
self.mhistory.append(self.history[self.hindex])
self.redraw_histmenu()
self.set_buttons(1)
if self.hindex == 0:
self.backbtn.set_sensitive(0)
self.back.set_sensitive(0)
else:
self.backbtn.set_sensitive(1)
self.back.set_sensitive(1)
self.fwdbtn.set_sensitive(1)
self.forward.set_sensitive(1)
except:
self.clear_history()
else:
self.backbtn.set_sensitive(0)
self.back.set_sensitive(0)
self.fwdbtn.set_sensitive(1)
self.forward.set_sensitive(1)
def fwd_clicked(self,obj,step=1):
if self.hindex+1 < len(self.history):
try:
self.hindex += step
self.active_person = self.db.get_person(self.history[self.hindex])
self.modify_statusbar()
self.update_display(0)
self.mhistory.append(self.history[self.hindex])
self.redraw_histmenu()
self.set_buttons(1)
if self.hindex == len(self.history)-1:
self.fwdbtn.set_sensitive(0)
self.forward.set_sensitive(0)
else:
self.fwdbtn.set_sensitive(1)
self.forward.set_sensitive(1)
self.backbtn.set_sensitive(1)
self.back.set_sensitive(1)
except:
self.clear_history()
else:
self.fwdbtn.set_sensitive(0)
self.forward.set_sensitive(0)
self.backbtn.set_sensitive(1)
self.back.set_sensitive(1)
2002-10-20 19:55:16 +05:30
def edit_button_clicked(self,obj):
2003-03-27 08:46:09 +05:30
cpage = self.views.get_current_page()
if cpage == PERSON_VIEW:
2002-10-20 19:55:16 +05:30
self.load_selected_people(obj)
elif cpage == FAMILY_VIEW2 or cpage == FAMILY_VIEW1:
self.load_person(self.active_person)
elif cpage == SOURCE_VIEW:
2002-10-20 19:55:16 +05:30
self.source_view.on_edit_clicked(obj)
elif cpage == PLACE_VIEW:
2002-10-20 19:55:16 +05:30
self.place_view.on_edit_clicked(obj)
elif cpage == MEDIA_VIEW:
self.media_view.on_edit_clicked(obj)
2002-10-20 19:55:16 +05:30
def add_button_clicked(self,obj):
2003-03-27 08:46:09 +05:30
cpage = self.views.get_current_page()
if cpage == PERSON_VIEW or cpage == FAMILY_VIEW2 or cpage == FAMILY_VIEW1:
2002-10-20 19:55:16 +05:30
self.load_new_person(obj)
elif cpage == SOURCE_VIEW:
2002-10-20 19:55:16 +05:30
self.source_view.on_add_clicked(obj)
elif cpage == PLACE_VIEW:
2002-10-21 06:48:07 +05:30
self.place_view.on_add_place_clicked(obj)
elif cpage == MEDIA_VIEW:
self.media_view.on_add_clicked(obj)
2002-10-20 19:55:16 +05:30
def remove_button_clicked(self,obj):
2003-03-27 08:46:09 +05:30
cpage = self.views.get_current_page()
if cpage == PERSON_VIEW or cpage == FAMILY_VIEW2 or cpage == FAMILY_VIEW1:
2002-10-20 19:55:16 +05:30
self.delete_person_clicked(obj)
elif cpage == SOURCE_VIEW:
2002-10-20 19:55:16 +05:30
self.source_view.on_delete_clicked(obj)
elif cpage == PLACE_VIEW:
2002-10-20 19:55:16 +05:30
self.place_view.on_delete_clicked(obj)
elif cpage == MEDIA_VIEW:
self.media_view.on_delete_clicked(obj)
2002-10-20 19:55:16 +05:30
def enable_buttons(self,val):
self.add_button.set_sensitive(val)
self.remove_button.set_sensitive(val)
self.edit_button.set_sensitive(val)
self.add_item.set_sensitive(val)
self.remove_item.set_sensitive(val)
self.edit_item.set_sensitive(val)
2002-10-20 19:55:16 +05:30
def on_show_plugin_status(self,obj):
Plugins.PluginStatus()
def on_sidebar_activate(self,obj):
val = obj.get_active()
self.enable_sidebar(val)
2002-10-20 19:55:16 +05:30
def enable_sidebar(self,val):
if val:
self.sidebar.show()
2003-03-27 08:46:09 +05:30
self.views.set_show_tabs(0)
2002-10-20 19:55:16 +05:30
else:
self.sidebar.hide()
2003-03-27 08:46:09 +05:30
self.views.set_show_tabs(1)
GrampsCfg.save_view(val)
2002-10-20 19:55:16 +05:30
def enable_filter(self,val):
if val:
self.filterbar.show()
else:
self.filterbar.hide()
def on_filter_activate(self,obj):
self.enable_filter(obj.get_active())
GrampsCfg.save_filter(obj.get_active())
2002-10-20 19:55:16 +05:30
def on_toolbar_activate(self,obj):
val = obj.get_active()
self.enable_toolbar(val)
def enable_toolbar(self,val):
if val:
self.toolbardock.show()
else:
self.toolbardock.hide()
GrampsCfg.save_toolbar_on(val)
2002-10-20 19:55:16 +05:30
def build_plugin_menus(self):
export_menu = self.gtop.get_widget("export1")
import_menu = self.gtop.get_widget("import1")
self.report_menu = self.gtop.get_widget("reports_menu")
self.tools_menu = self.gtop.get_widget("tools_menu")
2002-10-20 19:55:16 +05:30
self.report_menu.set_sensitive(0)
self.tools_menu.set_sensitive(0)
2002-10-20 19:55:16 +05:30
Plugins.load_plugins(const.docgenDir)
Plugins.load_plugins(os.path.expanduser("~/.gramps/docgen"))
Plugins.load_plugins(const.pluginsDir)
Plugins.load_plugins(os.path.expanduser("~/.gramps/plugins"))
2003-01-09 10:11:08 +05:30
Plugins.load_plugins(const.calendarDir)
Plugins.load_plugins(os.path.expanduser("~/.gramps/calendars"))
2002-10-20 19:55:16 +05:30
Plugins.build_report_menu(self.report_menu,self.menu_report)
Plugins.build_tools_menu(self.tools_menu,self.menu_tools)
2002-10-20 19:55:16 +05:30
self.RelClass = Plugins.relationship_class
self.relationship = self.RelClass(self.db)
2002-10-20 19:55:16 +05:30
def init_filters(self):
filter_list = []
all = GenericFilter.GenericFilter()
all.set_name(_("Entire Database"))
all.add_rule(GenericFilter.Everyone([]))
filter_list.append(all)
all = GenericFilter.GenericFilter()
all.set_name(_("Females"))
all.add_rule(GenericFilter.IsFemale([]))
filter_list.append(all)
all = GenericFilter.GenericFilter()
all.set_name(_("Males"))
all.add_rule(GenericFilter.IsMale([]))
filter_list.append(all)
all = GenericFilter.ParamFilter()
all.set_name(_("Name contains..."))
all.add_rule(GenericFilter.SearchName([]))
filter_list.append(all)
2002-10-20 19:55:16 +05:30
menu = GenericFilter.build_filter_menu(filter_list)
2002-10-20 19:55:16 +05:30
self.filter_list.set_menu(menu)
self.filter_list.set_history(0)
self.filter_list.connect('changed',self.on_filter_name_changed)
2002-10-20 19:55:16 +05:30
self.filter_text.set_sensitive(0)
def on_find_activate(self,obj):
"""Display the find box"""
if self.views.get_current_page() == PLACE_VIEW:
if self.find_place:
self.find_place.show()
else:
self.find_place = Find.FindPlace(self.find_goto_place,self.db)
elif self.views.get_current_page() == SOURCE_VIEW:
if self.find_source:
self.find_source.show()
else:
Find.FindSource(self.find_goto_source,self.db)
elif self.views.get_current_page() == MEDIA_VIEW:
if self.find_media:
self.find_media.show()
else:
Find.FindMedia(self.find_goto_media,self.db)
2002-10-20 19:55:16 +05:30
else:
if self.find_person:
self.find_person.show()
else:
self.find_person = Find.FindPerson(self.find_goto_person,self.db,None)
2002-10-20 19:55:16 +05:30
def on_findname_activate(self,obj):
"""Display the find box"""
pass
2003-04-04 11:18:25 +05:30
def find_goto_person(self,id):
2002-10-20 19:55:16 +05:30
"""Find callback to jump to the selected person"""
2003-03-23 08:56:55 +05:30
self.change_active_person(id)
2002-10-20 19:55:16 +05:30
self.goto_active_person()
self.update_display(0)
2003-04-04 11:18:25 +05:30
def find_goto_place(self,id):
2002-10-20 19:55:16 +05:30
"""Find callback to jump to the selected place"""
2003-04-04 11:18:25 +05:30
self.place_view.goto(id)
2002-10-20 19:55:16 +05:30
2003-04-04 11:18:25 +05:30
def find_goto_source(self,id):
2002-10-20 19:55:16 +05:30
"""Find callback to jump to the selected source"""
2003-04-04 11:18:25 +05:30
self.source_view.goto(id)
2002-10-20 19:55:16 +05:30
def find_goto_media(self,row):
"""Find callback to jump to the selected media"""
2003-04-04 11:18:25 +05:30
self.media_view.goto(row)
2002-10-20 19:55:16 +05:30
def home_page_activate(self,obj):
gnome.url_show(_HOMEPAGE)
2002-10-20 19:55:16 +05:30
def mailing_lists_activate(self,obj):
gnome.url_show(_MAILLIST)
2002-10-20 19:55:16 +05:30
def report_bug_activate(self,obj):
gnome.url_show(_BUGREPORT)
2002-10-20 19:55:16 +05:30
def on_merge_activate(self,obj):
"""Calls up the merge dialog for the selection"""
2003-03-27 08:46:09 +05:30
page = self.views.get_current_page()
if page == PERSON_VIEW:
mlist = self.people_view.get_selected_objects()
if len(mlist) != 2:
2003-02-24 10:21:57 +05:30
msg = _("Cannot merge people.")
msg2 = _("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.")
2003-02-24 10:21:57 +05:30
ErrorDialog(msg,msg2)
2002-10-20 19:55:16 +05:30
else:
import MergeData
p1 = self.db.get_person(mlist[0])
p2 = self.db.get_person(mlist[1])
MergeData.MergePeople(self,self.db,p1,p2,self.merge_update,
self.update_after_edit)
elif page == PLACE_VIEW:
2002-10-20 19:55:16 +05:30
self.place_view.merge()
def delete_event(self,widget, event):
"""Catch the destruction of the top window, prompt to save if needed"""
self.on_exit_activate(widget)
return 1
def on_exit_activate(self,obj):
"""Prompt to save on exit if needed"""
2004-02-29 01:45:48 +05:30
self.delete_abandoned_photos()
self.db.close()
gtk.main_quit()
2002-10-20 19:55:16 +05:30
def save_query(self):
"""Catch the reponse to the save on exit question"""
self.on_save_activate_quit()
self.delete_abandoned_photos()
2002-10-20 19:55:16 +05:30
self.db.close()
gtk.main_quit()
2002-10-20 19:55:16 +05:30
def save_query_noquit(self):
"""Catch the reponse to the save question, no quitting"""
self.on_save_activate_quit()
self.delete_abandoned_photos()
self.db.close()
2002-10-20 19:55:16 +05:30
def quit(self):
"""Catch the reponse to the save on exit question"""
self.delete_abandoned_photos()
2002-10-20 19:55:16 +05:30
self.db.close()
gtk.main_quit()
2002-10-20 19:55:16 +05:30
def close_noquit(self):
"""Close database and delete abandoned photos, no quit"""
self.delete_abandoned_photos()
self.db.close()
def delete_abandoned_photos(self):
"""
We only want to delete local objects, not external objects, however, we
can delete any thumbnail images. The thumbnails may or may not exist, depending
on if the image was previewed.
"""
self.db.set_people_view_maps(self.people_view.get_maps())
2002-10-20 19:55:16 +05:30
def on_about_activate(self,obj):
"""Displays the about box. Called from Help menu"""
pixbuf = gtk.gdk.pixbuf_new_from_file(const.logo)
2003-04-06 05:09:22 +05:30
if const.translators[0:11] == "TRANSLATORS":
2003-04-06 10:37:36 +05:30
trans = ''
2003-04-06 05:09:22 +05:30
else:
trans = const.translators
2002-10-20 19:55:16 +05:30
gnome.ui.About(const.progName,
const.version,
const.copyright,
const.comments,
const.authors,
const.documenters,
2003-04-06 05:09:22 +05:30
trans,
2002-10-20 19:55:16 +05:30
pixbuf).show()
def on_contents_activate(self,obj):
"""Display the GRAMPS manual"""
try:
gnome.help_display('gramps-manual','index')
except gobject.GError, msg:
ErrorDialog(_("Could not open help"),
str(msg))
2002-10-20 19:55:16 +05:30
def on_faq_activate(self,obj):
"""Display FAQ"""
try:
gnome.help_display('gramps-manual','faq')
except gobject.GError, msg:
ErrorDialog(_("Could not open help"),
str(msg))
2002-10-20 19:55:16 +05:30
def on_new_clicked(self,obj):
"""Prompt for permission to close the current database"""
DbPrompter.DbPrompter(self,1,self.topWindow)
def clear_database(self):
"""Clear out the database if permission was granted"""
return
2002-10-20 19:55:16 +05:30
def tool_callback(self,val):
if val:
self.import_tool_callback()
def import_tool_callback(self):
self.people_view.person_model.rebuild_data()
if Utils.wasHistory_broken():
self.clear_history()
2004-06-22 04:54:51 +05:30
Utils.clearHistory_broken()
self.people_view.change_db(self.db)
self.people_view.apply_filter()
if not self.active_person:
self.change_active_person(self.find_initial_person())
else:
self.goto_active_person()
self.place_view.change_db(self.db)
self.source_view.change_db(self.db)
self.media_view.change_db(self.db)
2002-10-20 19:55:16 +05:30
def full_update(self):
"""Brute force display update, updating all the pages"""
self.place_view.change_db(self.db)
self.people_view.change_db(self.db)
self.source_view.change_db(self.db)
self.media_view.change_db(self.db)
2002-10-20 19:55:16 +05:30
self.toolbar.set_style(GrampsCfg.toolbar)
def update_display(self,changed):
"""Incremental display update, update only the displayed page"""
2003-03-27 08:46:09 +05:30
page = self.views.get_current_page()
if page == PERSON_VIEW:
2004-05-02 09:40:33 +05:30
self.people_view.apply_filter()
elif page == FAMILY_VIEW1 or page == FAMILY_VIEW2:
2002-10-20 19:55:16 +05:30
self.family_view.load_family()
elif page == PEDIGREE_VIEW:
2002-10-20 19:55:16 +05:30
self.pedigree_view.load_canvas(self.active_person)
def on_tools_clicked(self,obj):
if self.active_person:
2004-02-28 09:21:59 +05:30
Plugins.ToolPlugins(self,self.db,self.active_person,
2002-10-20 19:55:16 +05:30
self.tool_callback)
def on_reports_clicked(self,obj):
if self.active_person:
2004-02-28 09:21:59 +05:30
Plugins.ReportPlugins(self,self.db,self.active_person)
2002-10-20 19:55:16 +05:30
def on_ok_button1_clicked(self,obj):
filename = self.filesel.get_filename()
2002-10-20 19:55:16 +05:30
if filename == "" or filename == None:
return
2003-02-24 10:21:57 +05:30
filename = os.path.normpath(os.path.abspath(filename))
self.filesel.destroy()
self.clear_database()
2004-04-10 09:08:48 +05:30
if self.auto_save_load(filename) == 0:
DbPrompter.DbPrompter(self,0,self.topWindow)
2002-10-20 19:55:16 +05:30
def on_help_dbopen_clicked(self,obj):
"""Display the relevant portion of GRAMPS manual"""
try:
gnome.help_display('gramps-manual','open-db')
except gobject.GError, msg:
ErrorDialog(_("Could not open help"),
str(msg))
self.dbopen_button = self.dbopen_fs.run()
2002-10-20 19:55:16 +05:30
def auto_save_load(self,filename):
2003-02-24 10:21:57 +05:30
filename = os.path.normpath(os.path.abspath(filename))
2002-10-20 19:55:16 +05:30
if os.path.isdir(filename):
dirname = filename
else:
dirname = os.path.dirname(filename)
self.active_person = None
2004-04-10 09:08:48 +05:30
return self.read_file(filename)
2002-10-20 19:55:16 +05:30
def read_gedcom(self,filename):
import ReadGedcom
2003-02-24 10:21:57 +05:30
filename = os.path.normpath(os.path.abspath(filename))
2002-10-20 19:55:16 +05:30
try:
ReadGedcom.importData(self.db,filename,None)
self.import_tool_callback()
except:
DisplayTrace.DisplayTrace()
def read_xml(self,filename):
import ReadXML
filename = os.path.normpath(os.path.abspath(os.path.join(filename,const.xmlFile)))
try:
ReadXML.importData(self.db,filename,None)
self.import_tool_callback()
except:
DisplayTrace.DisplayTrace()
def read_pkg(self,filename):
# Create tempdir, if it does not exist, then check for writability
tmpdir_path = os.path.expanduser("~/.gramps/tmp" )
if not os.path.isdir(tmpdir_path):
try:
os.mkdir(tmpdir_path,0700)
except:
DisplayTrace.DisplayTrace()
return
elif not os.access(tmpdir_path,os.W_OK):
ErrorDialog( _("Cannot unpak archive"),
_("Temporary directory %s is not writable") % tmpdir_path )
return
else: # tempdir exists and writable -- clean it up if not empty
files = os.listdir(tmpdir_path) ;
for fn in files:
os.remove( os.path.join(tmpdir_path,fn) )
try:
import TarFile
t = TarFile.ReadTarFile(filename,tmpdir_path)
t.extract()
t.close()
2002-10-20 19:55:16 +05:30
except:
DisplayTrace.DisplayTrace()
return
dbname = os.path.join(tmpdir_path,const.xmlFile)
try:
import ReadXML
ReadXML.importData(self.db,dbname,None)
except:
DisplayTrace.DisplayTrace()
# Clean up tempdir after ourselves
files = os.listdir(tmpdir_path)
for fn in files:
os.remove(os.path.join(tmpdir_path,fn))
os.rmdir(tmpdir_path)
self.import_tool_callback()
2002-10-20 19:55:16 +05:30
def read_file(self,filename):
self.topWindow.set_resizable(gtk.FALSE)
2003-02-24 10:21:57 +05:30
filename = os.path.normpath(os.path.abspath(filename))
2004-04-10 09:08:48 +05:30
new_db = 0
if os.path.isdir(filename):
ErrorDialog(_('Cannot open database'),
_('The selected file is a directory, not '
'a file.\nA GRAMPS database must be a file.'))
return 0
elif os.path.exists(filename):
if not os.access(filename,os.R_OK):
ErrorDialog(_('Cannot open database'),
_('You do not have read access to the selected '
'file.'))
return 0
elif not os.access(filename,os.W_OK):
ErrorDialog(_('Cannot open database'),
_('You do not have write access to the selected '
'file.'))
return 0
2002-10-20 19:55:16 +05:30
else:
2004-04-10 09:08:48 +05:30
new_db = 1
try:
if self.load_database(filename) == 1:
if filename[-1] == '/':
filename = filename[:-1]
name = os.path.basename(filename)
self.topWindow.set_title("%s - GRAMPS" % name)
else:
GrampsCfg.save_last_file("")
ErrorDialog(_('Cannot open database'),
_('The database file specified could not be opened file.'))
return 0
except db.DBAccessError, msg:
ErrorDialog(_('Cannot open database'),
_('%s could not be opened.' % filename) + '\n' + msg[1])
return 0
self.topWindow.set_resizable(gtk.TRUE)
self.people_view.apply_filter()
self.goto_active_person()
2004-04-10 09:08:48 +05:30
return 1
2003-05-17 09:44:13 +05:30
2002-10-20 19:55:16 +05:30
def on_ok_button2_clicked(self,obj):
filename = obj.get_filename()
2003-02-24 10:21:57 +05:30
filename = os.path.normpath(os.path.abspath(filename))
2002-10-20 19:55:16 +05:30
if filename:
Utils.destroy_passed_object(obj)
self.save_media(filename)
self.save_file(filename,_("No Comment Provided"))
2002-10-20 19:55:16 +05:30
def save_media(self,filename):
import RelImage
missmedia_action = 0
#-------------------------------------------------------------------------
def remove_clicked():
# File is lost => remove all references and the object itself
mobj = self.db.try_to_find_object_from_id(ObjectId)
for p in self.db.get_family_id_map().values():
2004-02-21 11:41:59 +05:30
nl = p.get_media_list()
for o in nl:
if o.get_reference_id() == ObjectId:
nl.remove(o)
2004-02-21 11:41:59 +05:30
p.set_media_list(nl)
for key in self.db.get_person_keys():
p = self.db.get_person(key)
2004-02-21 11:41:59 +05:30
nl = p.get_media_list()
for o in nl:
if o.get_reference_id() == ObjectId:
nl.remove(o)
2004-02-21 11:41:59 +05:30
p.set_media_list(nl)
for key in self.db.get_source_keys():
p = self.db.get_source(key)
2004-02-21 11:41:59 +05:30
nl = p.get_media_list()
for o in nl:
if o.get_reference_id() == ObjectId:
nl.remove(o)
2004-02-21 11:41:59 +05:30
p.set_media_list(nl)
for key in self.db.get_place_id_keys():
p = self.db.get_place_id(key)
2004-02-21 11:41:59 +05:30
nl = p.get_media_list()
for o in nl:
if o.get_reference_id() == ObjectId:
nl.remove(o)
2004-02-21 11:41:59 +05:30
p.set_media_list(nl)
trans = self.db.start_transaction()
self.db.remove_object(ObjectId)
2004-05-19 11:43:36 +05:30
self.db.add_transaction(trans,_("Save Media Object"))
def leave_clicked():
# File is lost => do nothing, leave as is
pass
def select_clicked():
choose = gtk.FileChooserDialog('Open GRAMPS database',
None,
gtk.FILE_CHOOSER_ACTION_OPEN,
(gtk.STOCK_CANCEL,
gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN,
gtk.RESPONSE_OK))
filter = gtk.FileFilter()
filter.set_name(_('All files'))
filter.add_pattern('*')
choose.add_filter(filter)
response = choose.run()
if response == gtk.RESPONSE_OK:
name = choose.get_filename()
if os.path.isfile(name):
RelImage.import_media_object(name,filename,base)
object = self.db.try_to_find_object_from_id(ObjectId)
2004-05-19 11:43:36 +05:30
object.set_path(name)
choose.destroy()
#-------------------------------------------------------------------------
for ObjectId in self.db.get_object_keys():
object = self.db.try_to_find_object_from_id(ObjectId)
if 0:
oldfile = object.get_path()
(base,ext) = os.path.splitext(os.path.basename(oldfile))
newfile = os.path.join(filename,os.path.basename(oldfile))
object.set_path(newfile)
if os.path.isfile(oldfile):
RelImage.import_media_object(oldfile,filename,base)
else:
if self.cl:
print "Warning: media file %s was not found," \
% os.path.basename(oldfile), "so it was ignored."
else:
# File is lost => ask what to do
if missmedia_action == 0:
mmd = MissingMediaDialog(_("Media object could not be found"),
2004-06-22 04:54:51 +05:30
_("%(file_name)s is referenced in the database, but no longer exists. "
"The file may have been deleted or moved to a different location. "
"You may choose to either remove the reference from the database, "
"keep the reference to the missing file, or select a new file."
) % { 'file_name' : oldfile },
remove_clicked, leave_clicked, select_clicked)
missmedia_action = mmd.default_action
elif missmedia_action == 1:
remove_clicked()
elif missmedia_action == 2:
leave_clicked()
elif missmedia_action == 3:
select_clicked()
2002-10-20 19:55:16 +05:30
def save_file(self,filename,comment):
path = filename
2003-02-24 10:21:57 +05:30
filename = os.path.normpath(os.path.abspath(filename))
self.status_text(_("Saving %s ...") % filename)
2002-10-20 19:55:16 +05:30
if os.path.exists(filename):
2003-05-18 23:01:45 +05:30
if not os.path.isdir(filename):
DbPrompter.DbPrompter(self,0,self.topWindow)
2003-02-24 10:21:57 +05:30
self.displayError(_("Database could not be opened"),
_("%s is not a directory.") % filename + ' ' + \
_("You should select a directory that contains a "
"data.gramps file."))
2002-10-20 19:55:16 +05:30
return
else:
try:
os.mkdir(filename)
except (OSError,IOError), msg:
2003-02-24 10:21:57 +05:30
emsg = _("Could not create %s") % filename
2003-04-02 04:58:21 +05:30
ErrorDialog(emsg,_("An error was detected while attempting to create the file. ",
2003-02-24 10:21:57 +05:30
'The operating system reported "%s"' % str(msg)))
2002-10-20 19:55:16 +05:30
return
except:
2003-02-24 10:21:57 +05:30
ErrorDialog(_("Could not create %s") % filename,
_("An error was detected while trying to create the file"))
2002-10-20 19:55:16 +05:30
return
old_file = filename
filename = "%s/%s" % (filename,self.db.get_base())
try:
self.db.clear_added_media_objects()
2002-10-20 19:55:16 +05:30
except (OSError,IOError), msg:
2003-02-24 10:21:57 +05:30
emsg = _("Could not create %s") % filename
ErrorDialog(emsg,msg)
2002-10-20 19:55:16 +05:30
return
self.db.set_save_path(old_file)
2002-10-20 19:55:16 +05:30
GrampsCfg.save_last_file(old_file)
filename = self.db.get_save_path()
2002-10-20 19:55:16 +05:30
if filename[-1] == '/':
filename = filename[:-1]
name = os.path.basename(filename)
self.topWindow.set_title("%s - GRAMPS" % name)
self.status_text("")
2002-10-20 19:55:16 +05:30
self.statusbar.set_progress_percentage(0.0)
def load_selected_people(self,obj):
"""Display the selected people in the EditPerson display"""
mlist = self.people_view.get_selected_objects()
2004-02-22 10:27:06 +05:30
if mlist and self.active_person.get_id() == mlist[0]:
self.load_person(self.active_person)
2002-10-20 19:55:16 +05:30
def load_active_person(self,obj):
self.load_person(self.active_person)
2003-06-25 09:06:48 +05:30
def update_person_list(self,person):
self.people_view.add_to_person_list(person,0)
2002-10-20 19:55:16 +05:30
def load_new_person(self,obj):
2003-01-12 10:52:21 +05:30
self.active_person = RelLib.Person()
2002-10-20 19:55:16 +05:30
try:
EditPerson.EditPerson(self,self.active_person,self.db,
2002-10-20 19:55:16 +05:30
self.new_after_edit)
except:
DisplayTrace.DisplayTrace()
def delete_person_clicked(self,obj):
cpage = self.views.get_current_page()
if cpage == PERSON_VIEW:
mlist = self.people_view.get_selected_objects()
else:
mlist = [ self.active_person.get_id() ]
2002-12-29 11:14:35 +05:30
for sel in mlist:
p = self.db.get_person(sel)
self.active_person = p
2002-12-29 11:14:35 +05:30
name = GrampsCfg.nameof(p)
2002-10-20 19:55:16 +05:30
2003-02-24 10:21:57 +05:30
QuestionDialog(_('Delete %s?') % name,
_('Deleting the person will remove the person '
2003-02-24 10:21:57 +05:30
'from the database. The data can only be '
'recovered by closing the database without saving '
'changes. This change will become permanent '
'after you save the database.'),
2003-03-23 09:20:59 +05:30
_('_Delete Person'),
2003-02-24 10:21:57 +05:30
self.delete_person_response)
2002-10-20 19:55:16 +05:30
self.update_display(0)
2002-10-20 19:55:16 +05:30
def delete_person_response(self):
trans = self.db.start_transaction()
n = self.active_person.get_primary_name().get_regular_name()
if self.db.get_default_person() == self.active_person:
self.db.set_default_person(None)
for family_id in self.active_person.get_family_id_list():
if not family_id:
continue
family = self.db.find_family_from_id(family_id)
if self.active_person.get_id() == family.get_father_id():
if family.get_mother_id() == None:
for child_id in family.get_child_id_list():
child = self.db.try_to_find_person_from_id(child_id)
child.remove_parent_family_id(family.get_id())
self.db.commit_person(child,trans)
self.db.delete_family(family.get_id(),trans)
2002-10-20 19:55:16 +05:30
else:
family.set_father_id(None)
2002-10-20 19:55:16 +05:30
else:
if family.get_father_id() == None:
for child_id in family.get_child_id_list():
child = self.db.try_to_find_person_from_id(child_id)
child.remove_parent_family_id(family)
self.db.commit_person(child,trans)
self.db.delete_family(family,trans)
2002-10-20 19:55:16 +05:30
else:
family.set_mother_id(None)
self.db.commit_family(family,trans)
for (family_id,mrel,frel) in self.active_person.get_parent_family_id_list():
if family_id:
family = self.db.find_family_from_id(family_id)
family.remove_child_id(self.active_person.get_id())
self.db.commit_family(family,trans)
id = self.active_person.get_id()
2004-02-16 02:19:34 +05:30
self.people_view.remove_from_person_list(self.active_person)
self.people_view.remove_from_history(id)
self.db.remove_person_id(id, trans)
if self.hindex >= 0:
self.active_person = self.db.try_to_find_person_from_id(self.history[self.hindex])
else:
self.change_active_person(None)
2004-05-19 11:43:36 +05:30
self.db.add_transaction(trans,_("Delete Person (%s)") % n)
self.redraw_histmenu()
2002-10-20 19:55:16 +05:30
def merge_update(self,p1,p2,old_id):
self.people_view.remove_from_person_list(p1,old_id)
self.people_view.remove_from_person_list(p2)
self.people_view.remove_from_history(p1,old_id)
self.people_view.remove_from_history(p2)
self.redraw_histmenu()
self.people_view.redisplay_person_list(p1)
2002-10-20 19:55:16 +05:30
self.update_display(0)
2003-05-23 09:38:03 +05:30
def goto_active_person(self,first=0):
self.people_view.goto_active_person(first)
def change_active_person(self,person,force=0):
if person == None:
self.set_buttons(0)
self.active_person = None
self.modify_statusbar()
elif self.active_person == None or \
person.get_id() != self.active_person.get_id():
self.active_person = self.db.try_to_find_person_from_id(person.get_id())
2003-04-04 11:18:25 +05:30
self.modify_statusbar()
self.set_buttons(1)
if person:
if self.hindex+1 < len(self.history):
self.history = self.history[0:self.hindex+1]
self.history.append(person.get_id())
self.mhistory.append(person.get_id())
self.hindex += 1
self.redraw_histmenu()
if self.hindex+1 < len(self.history):
self.fwdbtn.set_sensitive(1)
self.forward.set_sensitive(1)
else:
self.fwdbtn.set_sensitive(0)
self.forward.set_sensitive(0)
if self.hindex > 0:
self.backbtn.set_sensitive(1)
self.back.set_sensitive(1)
else:
self.backbtn.set_sensitive(0)
self.back.set_sensitive(0)
else:
self.active_person = self.db.try_to_find_person_from_id(person.get_id())
self.set_buttons(1)
2002-10-20 19:55:16 +05:30
def modify_statusbar(self):
2002-10-20 19:55:16 +05:30
if self.active_person == None:
self.status_text("")
2002-10-20 19:55:16 +05:30
else:
if GrampsCfg.status_bar <= 1:
pname = GrampsCfg.nameof(self.active_person)
name = "[%s] %s" % (self.active_person.get_gramps_id(),pname)
else:
2003-04-30 05:54:32 +05:30
name = self.display_relationship()
self.status_text(name)
2002-10-20 19:55:16 +05:30
return 0
2003-04-30 05:54:32 +05:30
def display_relationship(self):
default_person = self.db.get_default_person()
if not default_person:
return u''
2003-04-30 05:54:32 +05:30
try:
pname = GrampsCfg.nameof(default_person)
(name,plist) = self.relationship.get_relationship(
default_person,
self.active_person)
2003-04-30 05:54:32 +05:30
if name:
if plist == None:
return name
return _("%(relationship)s of %(person)s") % {
'relationship' : name, 'person' : pname }
2003-04-30 05:54:32 +05:30
else:
return ""
except:
DisplayTrace.DisplayTrace()
return ""
2004-06-22 04:54:51 +05:30
def fs_close_window(self,obj):
self.filesel.destroy()
2002-10-20 19:55:16 +05:30
def on_open_activate(self,obj):
choose = gtk.FileChooserDialog(_('GRAMPS: Open database'),
self.topWindow,
gtk.FILE_CHOOSER_ACTION_OPEN,
(gtk.STOCK_CANCEL,
gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN,
gtk.RESPONSE_OK))
# Always add automatic (macth all files) filter
filter = gtk.FileFilter()
filter.set_name(_('Automatic'))
filter.add_pattern('*')
choose.add_filter(filter)
# Always add native format filter
filter = gtk.FileFilter()
filter.set_name(_('GRAMPS databases'))
filter.add_mime_type('application/x-gramps')
choose.add_filter(filter)
for (importData,filter,mime_type) in Plugins._imports:
choose.add_filter(filter)
if GrampsCfg.lastfile:
choose.set_filename(GrampsCfg.lastfile)
response = choose.run()
if response == gtk.RESPONSE_OK:
filename = choose.get_filename()
filename = os.path.normpath(os.path.abspath(filename))
self.clear_database()
filetype = gnome.vfs.get_mime_type(filename)
(junk,the_file) = os.path.split(filename)
if filetype == 'application/x-gramps':
if self.auto_save_load(filename) == 0:
DbPrompter.DbPrompter(self,0,self.topWindow)
else:
opened = 0
for (importData,filter,mime_type) in Plugins._imports:
if filetype == mime_type or the_file == mime_type:
OkDialog( _("Opening non-native format"),
2004-06-28 06:57:37 +05:30
_("New gramps database has to be set up "
"when opening non-native formats. The "
"following dialog will let you select "
"the new database."),
self.topWindow)
DbPrompter.NewNativeDbPrompter(self,self.topWindow,filename)
importData(self.db,filename)
self.import_tool_callback()
opened = 1
break
if not opened:
ErrorDialog( _("Could not open file: %s") % filename,
_('The type "%s" is not in the list of known file types') % filetype )
choose.destroy()
def on_import_activate(self,obj):
choose = gtk.FileChooserDialog(_('GRAMPS: Import database'),
self.topWindow,
gtk.FILE_CHOOSER_ACTION_OPEN,
(gtk.STOCK_CANCEL,
gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN,
gtk.RESPONSE_OK))
# Always add automatic (macth all files) filter
filter = gtk.FileFilter()
filter.set_name(_('Automatic'))
filter.add_pattern('*')
choose.add_filter(filter)
# FIXME: Uncomment when we have grdb importer
#
# # Always add native format filter
# filter = gtk.FileFilter()
# filter.set_name(_('GRAMPS databases'))
# filter.add_mime_type('application/x-gramps')
# choose.add_filter(filter)
for (importData,filter,mime_type) in Plugins._imports:
choose.add_filter(filter)
if GrampsCfg.lastfile:
choose.set_filename(GrampsCfg.lastfile)
response = choose.run()
if response == gtk.RESPONSE_OK:
filename = choose.get_filename()
filename = os.path.normpath(os.path.abspath(filename))
filetype = gnome.vfs.get_mime_type(filename)
(junk,the_file) = os.path.split(filename)
# FIXME: Uncomment when we have grdb importer
#
# if filetype == 'application/x-gramps':
# if self.auto_save_load(filename) == 0:
# DbPrompter.DbPrompter(self,0,self.topWindow)
# else:
if True:
opened = 0
for (importData,filter,mime_type) in Plugins._imports:
if filetype == mime_type or the_file == mime_type:
print mime_type
print "Keys before:", self.db.get_person_keys()
importData(self.db,filename)
self.import_tool_callback()
opened = 1
print "Keys after:", self.db.get_person_keys()
break
if not opened:
ErrorDialog( _("Could not open file: %s") % filename,
_('The type "%s" is not in the list of known file types') % filetype )
choose.destroy()
def on_export_activate(self,obj):
choose = gtk.FileChooserDialog(_('GRAMPS: Export database'),
self.topWindow,
gtk.FILE_CHOOSER_ACTION_SAVE,
(gtk.STOCK_CANCEL,
gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN,
gtk.RESPONSE_OK))
# Always add automatic (macth all files) filter
filter = gtk.FileFilter()
filter.set_name(_('By extension'))
filter.add_pattern('*')
choose.add_filter(filter)
# FIXME: Uncomment when we have grdb importer
#
# # Always add native format filter
# filter = gtk.FileFilter()
# filter.set_name(_('GRAMPS databases'))
# filter.add_mime_type('application/x-gramps')
# choose.add_filter(filter)
for (exportData,filter,pattern_list) in Plugins._exports:
choose.add_filter(filter)
if GrampsCfg.lastfile:
choose.set_filename(GrampsCfg.lastfile)
response = choose.run()
if response == gtk.RESPONSE_OK:
filename = choose.get_filename()
filename = os.path.normpath(os.path.abspath(filename))
(junk,the_file) = os.path.split(filename)
# FIXME: Uncomment when we have grdb importer
#
# if filetype == 'application/x-gramps':
# if self.auto_save_load(filename) == 0:
# DbPrompter.DbPrompter(self,0,self.topWindow)
# else:
if True:
opened = 0
for (exportData,filter,pattern_list) in Plugins._exports:
for pattern in pattern_list:
if filter.filter((filename,None,None,None)):
exportData(self.db,filename)
opened = 1
break
if not opened:
ErrorDialog( _("Could not write file: %s") % filename,
_('The type is not in the list of known file types') )
choose.destroy()
2004-02-29 01:45:48 +05:30
def on_revert_activate(self,obj):
pass
2002-10-20 19:55:16 +05:30
def on_person_list1_activate(self,obj):
"""Switches to the person list view"""
self.views.set_current_page(PERSON_VIEW)
2002-10-20 19:55:16 +05:30
def on_family_activate(self,obj):
"""Switches to the family view"""
if GrampsCfg.familyview == 0:
self.on_family1_activate(obj)
else:
self.on_family2_activate(obj)
2002-10-20 19:55:16 +05:30
def on_family1_activate(self,obj):
"""Switches to the family view"""
self.views.set_current_page(FAMILY_VIEW1)
def on_family2_activate(self,obj):
"""Switches to the family view"""
self.views.set_current_page(FAMILY_VIEW2)
2002-10-20 19:55:16 +05:30
def on_pedigree1_activate(self,obj):
"""Switches to the pedigree view"""
self.views.set_current_page(PEDIGREE_VIEW)
2002-10-20 19:55:16 +05:30
def on_sources_activate(self,obj):
"""Switches to the sources view"""
self.views.set_current_page(SOURCE_VIEW)
2002-10-20 19:55:16 +05:30
def on_places_activate(self,obj):
"""Switches to the places view"""
self.status_text(_('Updating display...'))
self.views.set_current_page(PLACE_VIEW)
self.modify_statusbar()
2002-10-20 19:55:16 +05:30
def on_media_activate(self,obj):
"""Switches to the media view"""
self.views.set_current_page(MEDIA_VIEW)
2002-10-20 19:55:16 +05:30
2003-03-27 08:46:09 +05:30
def on_views_switch_page(self,obj,junk,page):
2002-10-20 19:55:16 +05:30
"""Load the appropriate page after a notebook switch"""
if page == PERSON_VIEW:
2002-10-20 19:55:16 +05:30
self.enable_buttons(1)
self.people_view.goto_active_person()
2002-10-20 19:55:16 +05:30
self.merge_button.set_sensitive(1)
elif page == FAMILY_VIEW1 or page == FAMILY_VIEW2:
self.enable_buttons(1)
2002-10-20 19:55:16 +05:30
self.merge_button.set_sensitive(0)
self.family_view.load_family()
elif page == PEDIGREE_VIEW:
self.enable_buttons(0)
2002-10-20 19:55:16 +05:30
self.merge_button.set_sensitive(0)
self.pedigree_view.load_canvas(self.active_person)
elif page == SOURCE_VIEW:
2002-10-20 19:55:16 +05:30
self.enable_buttons(1)
self.merge_button.set_sensitive(0)
elif page == PLACE_VIEW:
2002-10-20 19:55:16 +05:30
self.enable_buttons(1)
self.merge_button.set_sensitive(1)
elif page == MEDIA_VIEW:
2002-10-20 19:55:16 +05:30
self.enable_buttons(1)
self.merge_button.set_sensitive(0)
def on_apply_filter_clicked(self,obj):
self.people_view.apply_filter_clicked()
2002-10-20 19:55:16 +05:30
def on_filter_name_changed(self,obj):
filter = obj.get_menu().get_active().get_data('filter')
qual = filter.need_param
2002-10-20 19:55:16 +05:30
if qual:
self.filter_text.show()
self.filter_text.set_sensitive(1)
2002-10-20 19:55:16 +05:30
else:
self.filter_text.hide()
self.filter_text.set_sensitive(0)
2002-10-20 19:55:16 +05:30
def new_after_edit(self,epo,trans):
2002-10-20 19:55:16 +05:30
if epo:
if epo.person.get_id() == "":
self.db.add_person(epo.person,trans)
2002-10-20 19:55:16 +05:30
else:
self.db.add_person_no_map(epo.person,epo.person.get_id(),trans)
2002-10-20 19:55:16 +05:30
self.change_active_person(epo.person)
self.people_view.add_to_person_list(epo.person)
if self.views.get_current_page() in [FAMILY_VIEW1,FAMILY_VIEW2]:
self.family_view.load_family()
2002-10-20 19:55:16 +05:30
def update_after_newchild(self,family,person,plist):
self.family_view.load_family(family)
self.people_view.redisplay_person_list(person)
2002-10-20 19:55:16 +05:30
for p in plist:
self.place_view.new_place_after_edit(p)
def update_after_edit(self,epo,change=1):
2002-10-20 19:55:16 +05:30
if epo:
if change:
self.people_view.redisplay_person_list(epo.person)
else:
iter = self.people_view.person_model.get_iter((0,))
id = epo.person.get_id()
path = self.people_view.person_model.on_get_path(id)
self.people_view.person_model.row_changed(path,iter)
2002-10-20 19:55:16 +05:30
self.update_display(0)
def update_after_merge(self,person,old_id):
if person:
self.people_view.redisplay_person_list(person)
2002-10-20 19:55:16 +05:30
self.update_display(0)
def load_person(self,person):
if person:
try:
EditPerson.EditPerson(self, person, self.db, self.update_after_edit)
2002-10-20 19:55:16 +05:30
except:
DisplayTrace.DisplayTrace()
def list_item(self,label,filter):
l = gtk.Label(label)
l.set_alignment(0,0.5)
l.show()
c = gtk.ListItem()
c.add(l)
c.set_data('d',filter)
c.show()
return c
def parent_name(self,person):
if person == None:
return _("Unknown")
else:
return GrampsCfg.nameof(person)
2004-06-22 04:54:51 +05:30
2002-10-20 19:55:16 +05:30
def load_progress(self,value):
self.statusbar.set_progress_percentage(value)
while gtk.events_pending():
gtk.main_iteration()
2002-10-20 19:55:16 +05:30
def status_text(self,text):
self.statusbar.set_status(text)
while gtk.events_pending():
gtk.main_iteration()
2002-10-20 19:55:16 +05:30
def post_load(self,name):
self.db.set_save_path(name)
res = self.db.get_researcher()
2002-10-20 19:55:16 +05:30
owner = GrampsCfg.get_researcher()
if res.get_name() == "" and owner.get_name():
self.db.set_researcher(owner)
2002-10-20 19:55:16 +05:30
self.setup_bookmarks()
GrampsCfg.save_last_file(name)
self.gtop.get_widget("filter").set_text("")
self.statusbar.set_progress_percentage(1.0)
self.people_view.change_db(self.db)
self.place_view.change_db(self.db)
self.source_view.change_db(self.db)
self.media_view.change_db(self.db)
#self.full_update()
2004-02-21 11:41:59 +05:30
self.change_active_person(self.find_initial_person())
self.statusbar.set_progress_percentage(0.0)
return 1
def find_initial_person(self):
person = self.db.get_default_person()
if not person:
2004-02-21 11:41:59 +05:30
the_ids = self.db.get_person_keys()
if the_ids:
the_ids.sort()
person = self.db.get_person(the_ids[0])
return person
2002-10-20 19:55:16 +05:30
def load_database(self,name):
filename = name
2003-04-04 11:18:25 +05:30
self.status_text(_("Loading %s...") % name)
2004-04-10 09:08:48 +05:30
2002-10-20 19:55:16 +05:30
if self.db.load(filename,self.load_progress) == 0:
self.status_text('')
2002-10-20 19:55:16 +05:30
return 0
2004-04-10 09:08:48 +05:30
self.status_text('')
self.db.clear_added_media_objects()
2002-10-20 19:55:16 +05:30
return self.post_load(name)
def setup_bookmarks(self):
self.bookmarks = Bookmarks.Bookmarks(self.db,self.db.get_bookmarks(),
2002-10-20 19:55:16 +05:30
self.gtop.get_widget("jump_to"),
self.bookmark_callback)
2003-02-24 10:21:57 +05:30
def displayError(self,msg,msg2):
ErrorDialog(msg,msg2)
self.status_text("")
2002-10-20 19:55:16 +05:30
def complete_rebuild(self):
self.people_view.apply_filter()
self.goto_active_person()
self.modify_statusbar()
2002-10-20 19:55:16 +05:30
def on_home_clicked(self,obj):
temp = self.db.get_default_person()
2002-10-20 19:55:16 +05:30
if temp:
self.change_active_person(temp)
self.update_display(0)
else:
ErrorDialog(_("No Home Person has been set."),
_("The Home Person may be set from the Settings menu."))
2002-10-20 19:55:16 +05:30
def on_add_bookmark_activate(self,obj):
if self.active_person:
self.bookmarks.add(self.active_person.get_id())
2002-10-20 19:55:16 +05:30
name = GrampsCfg.nameof(self.active_person)
self.status_text(_("%s has been bookmarked") % name)
2002-10-20 19:55:16 +05:30
gtk.timeout_add(5000,self.modify_statusbar)
else:
WarningDialog(_("Could Not Set a Bookmark"),
_("A bookmark could not be set because "
"no one was selected."))
2002-10-20 19:55:16 +05:30
def on_edit_bookmarks_activate(self,obj):
self.bookmarks.edit()
2004-02-22 10:27:06 +05:30
def bookmark_callback(self,obj,person_id):
old_person = self.active_person
person = self.db.try_to_find_person_from_id(person_id)
try:
self.change_active_person(person)
self.update_display(0)
except TypeError:
WarningDialog(_("Could not go to a Person"),
_("Either stale bookmark or broken history "
"caused by IDs reorder."))
self.clear_history()
self.change_active_person(old_person)
self.update_display(0)
2002-10-20 19:55:16 +05:30
def on_default_person_activate(self,obj):
if self.active_person:
name = self.active_person.get_primary_name().get_regular_name()
QuestionDialog(_('Set %s as the Home Person') % name,
_('Once a Home Person is defined, pressing the '
'Home button on the toolbar will make the home '
'person the active person.'),
2003-03-23 09:20:59 +05:30
_('_Set Home Person'),
2003-02-24 10:21:57 +05:30
self.set_person)
2002-10-20 19:55:16 +05:30
def set_person(self):
self.db.set_default_person(self.active_person)
2002-10-20 19:55:16 +05:30
def export_callback(self,obj,plugin_function):
"""Call the export plugin, with the active person and database"""
if self.active_person:
plugin_function(self.db,self.active_person)
else:
ErrorDialog(_('A person must be selected to export'),
_('Exporting requires that an active person be selected. '
'Please select a person and try again.'))
2002-10-20 19:55:16 +05:30
def import_callback(self,obj,plugin_function):
"""Call the import plugin"""
plugin_function(self.db,self.active_person,self.import_tool_callback)
self.people_view.person_model.rebuild_data()
self.topWindow.set_title("%s - GRAMPS" % self.db.get_save_path())
2002-10-20 19:55:16 +05:30
def on_preferences_activate(self,obj):
GrampsCfg.display_preferences_box(self.db)
def menu_report(self,obj,task):
"""Call the report plugin selected from the menus"""
if self.active_person:
task(self.db,self.active_person)
def menu_tools(self,obj,task):
"""Call the tool plugin selected from the menus"""
if self.active_person:
task(self.db,self.active_person,self.tool_callback,self)
2002-10-20 19:55:16 +05:30
def on_main_key_release_event(self,obj,event):
"""Respond to the insert and delete buttons in the person list"""
2003-03-31 07:03:40 +05:30
pass
2002-10-20 19:55:16 +05:30
#if event.keyval == GDK.Delete:
# self.on_delete_person_clicked(obj)
#elif event.keyval == GDK.Insert:
# self.load_new_person(obj)
2003-03-31 07:03:40 +05:30
def open_example(self,obj):
pass
2003-03-31 07:03:40 +05:30
2002-10-20 19:55:16 +05:30
DARKEN = 1.4
def ms_shift_color_component (component, shift_by):
if shift_by > 1.0 :
result = int(component * (2 - shift_by))
else:
result = 0xffff - shift_by * (0xffff - component)
return (result & 65535)
def modify_color(color):
red = ms_shift_color_component(color.red,DARKEN)
green = ms_shift_color_component(color.green,DARKEN)
blue = ms_shift_color_component(color.blue,DARKEN)
return (red,green,blue)
def set_panel(obj):
style = obj.get_style().copy()
color = style.bg[gtk.STATE_NORMAL]
(r,g,b) = modify_color(color)
new_color = obj.get_colormap().alloc_color(r,g,b)
style.bg[gtk.STATE_NORMAL] = new_color
style.bg[gtk.STATE_PRELIGHT] = new_color
style.bg[gtk.STATE_ACTIVE] = new_color
style.bg[gtk.STATE_INSENSITIVE] = new_color
style.bg[gtk.STATE_SELECTED] = new_color
obj.set_style(style)
#-------------------------------------------------------------------------
#
# Start it all
#
#-------------------------------------------------------------------------
if __name__ == '__main__':
Gramps(None)
gtk.main()