299 lines
11 KiB
Python
299 lines
11 KiB
Python
#
|
|
# Gramps - a GTK+/GNOME based genealogy program
|
|
#
|
|
# Copyright (C) 2000-2006 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$
|
|
|
|
#-------------------------------------------------------------------------
|
|
#
|
|
# Python classes
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
from gettext import gettext as _
|
|
|
|
#-------------------------------------------------------------------------
|
|
#
|
|
# GTK libraries
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
import gtk
|
|
|
|
#-------------------------------------------------------------------------
|
|
#
|
|
# GRAMPS classes
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
from widgets import SimpleButton
|
|
from _GrampsTab import GrampsTab
|
|
import Errors
|
|
|
|
_KP_ENTER = gtk.gdk.keyval_from_name("KP_Enter")
|
|
_RETURN = gtk.gdk.keyval_from_name("Return")
|
|
_DEL = gtk.gdk.keyval_from_name("Delete")
|
|
_ADD = gtk.gdk.keyval_from_name("Insert")
|
|
_OPEN = gtk.gdk.keyval_from_name("o")
|
|
_LEFT = gtk.gdk.keyval_from_name("Left")
|
|
_RIGHT = gtk.gdk.keyval_from_name("Right")
|
|
|
|
#-------------------------------------------------------------------------
|
|
#
|
|
# Classes
|
|
#
|
|
#-------------------------------------------------------------------------
|
|
class ButtonTab(GrampsTab):
|
|
"""
|
|
This class derives from the base GrampsTab, yet is not a usable Tab. It
|
|
serves as another base tab for classes which need an Add/Edit/Remove button
|
|
combination.
|
|
"""
|
|
|
|
_MSG = {
|
|
'add' : _('Add'),
|
|
'del' : _('Remove'),
|
|
'edit' : _('Edit'),
|
|
'share' : _('Share'),
|
|
'jump' : _('Jump To'),
|
|
'up' : _('Move Up'),
|
|
'down' : _('Move Down'),
|
|
}
|
|
|
|
def __init__(self, dbstate, uistate, track, name, share_button=False,
|
|
move_buttons=False, jump_button=False):
|
|
"""
|
|
Similar to the base class, except after Build.
|
|
|
|
@param dbstate: The database state. Contains a reference to
|
|
the database, along with other state information. The GrampsTab
|
|
uses this to access the database and to pass to and created
|
|
child windows (such as edit dialogs).
|
|
@type dbstate: DbState
|
|
@param uistate: The UI state. Used primarily to pass to any created
|
|
subwindows.
|
|
@type uistate: DisplayState
|
|
@param track: The window tracking mechanism used to manage windows.
|
|
This is only used to pass to generted child windows.
|
|
@type track: list
|
|
@param name: Notebook label name
|
|
@type name: str/unicode
|
|
@param share_button: Add a share button to the Notebook tab or not
|
|
@type name: bool
|
|
@param move_buttons: Add up and down button to the Notebook tab or not
|
|
@type name: bool
|
|
"""
|
|
self.dirty_selection = False
|
|
GrampsTab.__init__(self,dbstate, uistate, track, name)
|
|
self.tooltips = gtk.Tooltips()
|
|
self.create_buttons(share_button, move_buttons, jump_button)
|
|
|
|
def create_buttons(self, share_button, move_buttons, jump_button):
|
|
"""
|
|
Create a button box consisting of three buttons, one for Add,
|
|
one for Edit, and one for Delete.
|
|
|
|
Add buttons for Share, Move and Jump depending on parameters. This
|
|
button box is then appended hbox (self).
|
|
"""
|
|
self.add_btn = SimpleButton(gtk.STOCK_ADD, self.add_button_clicked)
|
|
self.edit_btn = SimpleButton(gtk.STOCK_EDIT, self.edit_button_clicked)
|
|
self.del_btn = SimpleButton(gtk.STOCK_REMOVE, self.del_button_clicked)
|
|
|
|
self.tooltips.set_tip(self.add_btn, self._MSG['add'])
|
|
self.tooltips.set_tip(self.edit_btn, self._MSG['edit'])
|
|
self.tooltips.set_tip(self.del_btn, self._MSG['del'])
|
|
|
|
if share_button:
|
|
self.share_btn = SimpleButton(gtk.STOCK_INDEX, self.share_button_clicked)
|
|
self.tooltips.set_tip(self.share_btn, self._MSG['share'])
|
|
else:
|
|
self.share_btn = None
|
|
|
|
if move_buttons:
|
|
self.up_btn = SimpleButton(gtk.STOCK_GO_UP, self.up_button_clicked)
|
|
self.tooltips.set_tip(self.up_btn, self._MSG['up'])
|
|
self.down_btn = SimpleButton(gtk.STOCK_GO_DOWN,
|
|
self.down_button_clicked)
|
|
self.tooltips.set_tip(self.down_btn, self._MSG['down'])
|
|
else:
|
|
self.up_btn = None
|
|
self.down_btn = None
|
|
|
|
if self.dbstate.db.readonly:
|
|
self.add_btn.set_sensitive(False)
|
|
self.del_btn.set_sensitive(False)
|
|
if share_button:
|
|
self.share_btn.set_sensitive(False)
|
|
if jump_button:
|
|
self.jump_btn.set_sensitive(False)
|
|
if move_buttons:
|
|
self.up_btn.set_sensitive(False)
|
|
self.down_btn.set_sensitive(False)
|
|
|
|
if jump_button:
|
|
self.jump_btn = SimpleButton(gtk.STOCK_JUMP_TO, self.jump_button_clicked)
|
|
self.tooltips.set_tip(self.jump_btn, self._MSG['jump'])
|
|
else:
|
|
self.jump_btn = None
|
|
|
|
hbox = gtk.HBox()
|
|
hbox.set_spacing(6)
|
|
hbox.pack_start(self.add_btn, False)
|
|
if share_button:
|
|
hbox.pack_start(self.share_btn, False)
|
|
hbox.pack_start(self.edit_btn, False)
|
|
hbox.pack_start(self.del_btn, False)
|
|
if move_buttons:
|
|
hbox.pack_start(self.up_btn, False)
|
|
hbox.pack_start(self.down_btn, False)
|
|
if jump_button:
|
|
hbox.pack_start(self.jump_btn, False)
|
|
hbox.show_all()
|
|
self.pack_start(hbox, False)
|
|
|
|
def double_click(self, obj, event):
|
|
"""
|
|
Handles the double click on list. If the double click occurs,
|
|
the Edit button handler is called
|
|
"""
|
|
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
|
|
try:
|
|
self.edit_button_clicked(obj)
|
|
except Errors.WindowActiveError:
|
|
pass
|
|
|
|
def key_pressed(self, obj, event):
|
|
"""
|
|
Handles the return key being pressed on list. If the key is pressed,
|
|
the Edit button handler is called
|
|
"""
|
|
if event.type == gtk.gdk.KEY_PRESS:
|
|
#print 'key pressed', event.keyval, event.state, _ADD
|
|
if event.keyval in (_RETURN, _KP_ENTER):
|
|
try:
|
|
self.edit_button_clicked(obj)
|
|
except Errors.WindowActiveError:
|
|
pass
|
|
elif event.keyval in (_DEL,) and self.del_btn:
|
|
if self.dirty_selection or self.dbstate.db.readonly:
|
|
return
|
|
self.del_button_clicked(obj)
|
|
elif event.keyval in (_ADD,) and self.add_btn:
|
|
if self.dirty_selection or self.dbstate.db.readonly:
|
|
return
|
|
self.add_button_clicked(obj)
|
|
elif event.keyval in (_OPEN,) and self.share_btn and \
|
|
event.state in (gtk.gdk.CONTROL_MASK,
|
|
gtk.gdk.CONTROL_MASK | gtk.gdk.MOD2_MASK):
|
|
self.share_button_clicked(obj)
|
|
elif event.keyval in (_LEFT,) and \
|
|
event.state in (gtk.gdk.MOD1_MASK,
|
|
gtk.gdk.MOD1_MASK | gtk.gdk.MOD2_MASK):
|
|
self.prev_page()
|
|
elif event.keyval in (_RIGHT,) and \
|
|
event.state in (gtk.gdk.MOD1_MASK,
|
|
gtk.gdk.MOD1_MASK | gtk.gdk.MOD2_MASK):
|
|
self.next_page()
|
|
else:
|
|
return
|
|
return True
|
|
|
|
def add_button_clicked(self, obj):
|
|
"""
|
|
Function called with the Add button is clicked. This function
|
|
should be overridden by the derived class.
|
|
"""
|
|
print "Uncaught Add clicked"
|
|
|
|
def share_button_clicked(self, obj):
|
|
"""
|
|
Function called with the Share button is clicked. This function
|
|
should be overridden by the derived class.
|
|
"""
|
|
print "Uncaught Share clicked"
|
|
|
|
def jump_button_clicked(self, obj):
|
|
"""
|
|
Function called with the Jump button is clicked. This function
|
|
should be overridden by the derived class.
|
|
"""
|
|
print "Uncaught Jump clicked"
|
|
|
|
def del_button_clicked(self, obj):
|
|
"""
|
|
Function called with the Delete button is clicked. This function
|
|
should be overridden by the derived class.
|
|
"""
|
|
print "Uncaught Delete clicked"
|
|
|
|
def edit_button_clicked(self, obj):
|
|
"""
|
|
Function called with the Edit button is clicked or the double
|
|
click is caught. This function should be overridden by the derived
|
|
class.
|
|
"""
|
|
print "Uncaught Edit clicked"
|
|
|
|
def up_button_clicked(self, obj):
|
|
"""
|
|
Function called with the Up button is clicked.
|
|
This function should be overridden by the derived class.
|
|
"""
|
|
print "Uncaught Up clicked"
|
|
|
|
def down_button_clicked(self, obj):
|
|
"""
|
|
Function called with the Down button is clicked.
|
|
This function should be overridden by the derived class.
|
|
"""
|
|
print "Uncaught Down clicked"
|
|
|
|
def _selection_changed(self, obj=None):
|
|
"""
|
|
Attached to the selection's 'changed' signal. Checks
|
|
to see if anything is selected. If it is, the edit and
|
|
delete buttons are enabled, otherwise the are disabled.
|
|
"""
|
|
# Comparing to None is important, as empty strings
|
|
# and 0 can be returned
|
|
# This method is called as callback on change, and can be called
|
|
# explicitly, dirty_selection must make sure they do not interact
|
|
if self.dirty_selection:
|
|
return
|
|
if self.get_selected() is not None:
|
|
self.edit_btn.set_sensitive(True)
|
|
if self.jump_btn:
|
|
self.jump_btn.set_sensitive(True)
|
|
if not self.dbstate.db.readonly:
|
|
self.del_btn.set_sensitive(True)
|
|
# note: up and down cannot be set unsensitive after clicked
|
|
# or they do not respond to a next click
|
|
#if self.up_btn :
|
|
# self.up_btn.set_sensitive(True)
|
|
# self.down_btn.set_sensitive(True)
|
|
else:
|
|
self.edit_btn.set_sensitive(False)
|
|
if self.jump_btn:
|
|
self.jump_btn.set_sensitive(False)
|
|
if not self.dbstate.db.readonly:
|
|
self.del_btn.set_sensitive(False)
|
|
# note: up and down cannot be set unsensitive after clicked
|
|
# or they do not respond to a next click
|
|
#if self.up_btn :
|
|
# self.up_btn.set_sensitive(False)
|
|
# self.down_btn.set_sensitive(False)
|