2007-09-08 Don Allingham <don@gramps-project.org>

* src/ViewManager.py: code cleanup
	* src/FontScale.py: code cleanup
	* src/GrampsWidgets.py: code cleanup
	* src/ExportOptions.py: code cleanup
	* src/GrampsDisplay.py: code cleanup
	* src/DateEdit.py: code cleanup
	* src/DbLoader.py: code cleanup



svn: r8951
This commit is contained in:
Don Allingham
2007-09-09 05:24:15 +00:00
parent 651e29ead4
commit 6d9dbfee49
8 changed files with 593 additions and 501 deletions

View File

@ -1,3 +1,12 @@
2007-09-08 Don Allingham <don@gramps-project.org>
* src/ViewManager.py: code cleanup
* src/FontScale.py: code cleanup
* src/GrampsWidgets.py: code cleanup
* src/ExportOptions.py: code cleanup
* src/GrampsDisplay.py: code cleanup
* src/DateEdit.py: code cleanup
* src/DbLoader.py: code cleanup
2007-09-08 Benny Malengier <benny.malengier@gramps-project.org> 2007-09-08 Benny Malengier <benny.malengier@gramps-project.org>
* src/DataViews/_RelationView.py : expand/collapse, edit button on/off bug fix * src/DataViews/_RelationView.py : expand/collapse, edit button on/off bug fix
* src/GrampsWidgets.py : Expand widget, changes link labels * src/GrampsWidgets.py : Expand widget, changes link labels

View File

@ -264,7 +264,7 @@ class DateEditorDialog(ManagedWindow.ManagedWindow):
if response == gtk.RESPONSE_HELP: if response == gtk.RESPONSE_HELP:
GrampsDisplay.help('adv-dates') GrampsDisplay.help('adv-dates')
elif response == gtk.RESPONSE_DELETE_EVENT: elif response == gtk.RESPONSE_DELETE_EVENT:
return break
else: else:
if response == gtk.RESPONSE_OK: if response == gtk.RESPONSE_OK:
(the_quality, the_modifier, the_calendar, (the_quality, the_modifier, the_calendar,
@ -277,9 +277,11 @@ class DateEditorDialog(ManagedWindow.ManagedWindow):
value=the_value, value=the_value,
text=the_text) text=the_text)
self.close() self.close()
return
def build_menu_names(self, obj): def build_menu_names(self, obj):
"""
Define the menu entry for the ManagedWindows
"""
return (_("Date selection"), None) return (_("Date selection"), None)
def build_date_from_ui(self): def build_date_from_ui(self):

View File

@ -87,6 +87,9 @@ class DbLoader:
self.uistate = uistate self.uistate = uistate
def open_file(self): def open_file(self):
"""
Presents a file open dialog and opens the corresponding exsting file
"""
choose = gtk.FileChooserDialog( choose = gtk.FileChooserDialog(
_('GRAMPS: Open database'), _('GRAMPS: Open database'),
self.uistate.window, self.uistate.window,
@ -140,63 +143,6 @@ class DbLoader:
choose.destroy() choose.destroy()
return ('', '') return ('', '')
def new_file(self):
choose = gtk.FileChooserDialog(
_('GRAMPS: Create GRAMPS database'),
self.uistate.window,
gtk.FILE_CHOOSER_ACTION_SAVE,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_NEW, gtk.RESPONSE_OK))
# Always add automatic (macth all files) filter
add_all_files_filter(choose)
add_grdb_filter(choose)
default_dir = get_default_dir()
new_filename = Utils.get_new_filename('grdb', default_dir)
choose.set_current_folder(default_dir)
choose.set_current_name(os.path.split(new_filename)[1])
while (True):
response = choose.run()
if response == gtk.RESPONSE_OK:
filename = unicode(choose.get_filename(),
sys.getfilesystemencoding())
if self.check_errors(filename):
return ('','')
ext = os.path.splitext(filename)[1].lower()
if ext == ".ged":
filetype = const.APP_GEDCOM
elif ext == ".gramps":
filetype = const.APP_GRAMPS_XML
elif ext == ".grdb":
filetype = const.APP_GRAMPS
else:
filename = filename + ".grdb"
filetype = const.APP_GRAMPS
choose.destroy()
try:
self.dbstate.db.close()
except:
pass
self.read_file(filename, filetype)
try:
os.chdir(os.path.dirname(filename))
except:
return ('', '')
self.dbstate.db.db_is_open = True
return (filename, filetype)
else:
choose.destroy()
return ('', '')
choose.destroy()
return ('', '')
def save_as(self): def save_as(self):
choose = gtk.FileChooserDialog( choose = gtk.FileChooserDialog(
_('GRAMPS: Create GRAMPS database'), _('GRAMPS: Create GRAMPS database'),
@ -343,8 +289,8 @@ class DbLoader:
# Then we try all the known plugins # Then we try all the known plugins
(the_path, the_file) = os.path.split(filename) (the_path, the_file) = os.path.split(filename)
Config.set(Config.RECENT_IMPORT_DIR, the_path) Config.set(Config.RECENT_IMPORT_DIR, the_path)
for (importData, mime_filter, mime_type, native_format, format_name) \ for (importData, mime_filter, mime_type, native_format,
in import_list: format_name) in import_list:
if filetype == mime_type or the_file == mime_type: if filetype == mime_type or the_file == mime_type:
self.do_import(choose, importData, filename) self.do_import(choose, importData, filename)
return True return True

View File

@ -17,10 +17,24 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# #
"""
Provides the common export options for Exporters
"""
#-------------------------------------------------------------------------
#
# python modules
#
#-------------------------------------------------------------------------
import gtk import gtk
from gettext import gettext as _ from gettext import gettext as _
import RelLib #-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
import Config import Config
from BasicUtils import name_displayer from BasicUtils import name_displayer
@ -28,7 +42,7 @@ from Filters import GenericFilter, Rules
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# # WriterOptionBox
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class WriterOptionBox: class WriterOptionBox:
@ -38,13 +52,24 @@ class WriterOptionBox:
""" """
def __init__(self, person): def __init__(self, person):
self.person = person self.person = person
self.private = 0
self.restrict = 0
self.cfilter = None
self.restrict_check = None
self.private_check = None
self.filter_obj = None
def get_option_box(self): def get_option_box(self):
"""
Builds up a gtk.Table that contains the standard options
"""
table = gtk.Table(3, 2) table = gtk.Table(3, 2)
label = gtk.Label('Filter') label = gtk.Label('Filter')
self.filter_obj = gtk.ComboBox() self.filter_obj = gtk.ComboBox()
self.private_check = gtk.CheckButton(_('Do not include records marked private')) self.private_check = gtk.CheckButton(
self.restrict_check = gtk.CheckButton(_('Restrict data on living people')) _('Do not include records marked private'))
self.restrict_check = gtk.CheckButton(
_('Restrict data on living people'))
self.private_check.set_active(Config.get(Config.EXPORT_NO_PRIVATE)) self.private_check.set_active(Config.get(Config.EXPORT_NO_PRIVATE))
self.restrict_check.set_active(Config.get(Config.EXPORT_RESTRICT)) self.restrict_check.set_active(Config.get(Config.EXPORT_RESTRICT))
@ -57,14 +82,34 @@ class WriterOptionBox:
table.attach(self.private_check, 1, 2, 1, 2, yoptions=0) table.attach(self.private_check, 1, 2, 1, 2, yoptions=0)
table.attach(self.restrict_check, 1, 2, 2, 3, yoptions=0) table.attach(self.restrict_check, 1, 2, 2, 3, yoptions=0)
#filter_obj = self.topDialog.get_widget("filter") entire_db = GenericFilter()
entire_db.set_name(_("Entire Database"))
all = GenericFilter() the_filters = [entire_db]
all.set_name(_("Entire Database"))
the_filters = [all]
if self.person: if self.person:
the_filters += self.__define_person_filters()
from Filters import CustomFilters
the_filters.extend(CustomFilters.get_filters('Person'))
model = gtk.ListStore(str, object)
for item in the_filters:
model.append(row=[item.get_name(), item])
cell = gtk.CellRendererText()
self.filter_obj.pack_start(cell, True)
self.filter_obj.add_attribute(cell, 'text', 0)
self.filter_obj.set_model(model)
self.filter_obj.set_active(0)
table.show()
return table
def __define_person_filters(self):
"""
Add person filters if the active person is defined
"""
des = GenericFilter() des = GenericFilter()
des.set_name(_("Descendants of %s") % des.set_name(_("Descendants of %s") %
name_displayer.display(self.person)) name_displayer.display(self.person))
@ -82,27 +127,18 @@ class WriterOptionBox:
name_displayer.display(self.person)) name_displayer.display(self.person))
com.add_rule(Rules.Person.HasCommonAncestorWith( com.add_rule(Rules.Person.HasCommonAncestorWith(
[self.person.get_gramps_id()])) [self.person.get_gramps_id()]))
return [des, ans, com]
the_filters += [des, ans, com]
from Filters import CustomFilters
the_filters.extend(CustomFilters.get_filters('Person'))
model = gtk.ListStore(str, object)
for f in the_filters:
model.append(row=[f.get_name(), f])
cell = gtk.CellRendererText()
self.filter_obj.pack_start(cell, True)
self.filter_obj.add_attribute(cell, 'text', 0)
self.filter_obj.set_model(model)
self.filter_obj.set_active(0)
table.show()
return table
def parse_options(self): def parse_options(self):
"""
Extract the common values from the GTK widgets. After this function
is called, the following variables are defined:
private = privacy requested
restrict = restrict information on living peoplel
cfitler = return the GenericFilter selected
"""
self.restrict = self.restrict_check.get_active() self.restrict = self.restrict_check.get_active()
self.private = self.private_check.get_active() self.private = self.private_check.get_active()

View File

@ -17,7 +17,12 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# #
_swiss = [
"""
Provides a rough estimate of the width of a text string.
"""
SWISS = [
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
@ -45,7 +50,7 @@ _swiss = [
0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.584, 0.611, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.584, 0.611, 0.556,
0.556, 0.556, 0.556, 0.500, 0.556, 0.500] 0.556, 0.556, 0.556, 0.500, 0.556, 0.500]
_swiss_b = [ SWISS_B = [
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
@ -73,7 +78,7 @@ _swiss_b = [
0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.584, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.584, 0.611, 0.611,
0.611, 0.611, 0.611, 0.556, 0.611, 0.556] 0.611, 0.611, 0.611, 0.556, 0.611, 0.556]
_swiss_i = [ SWISS_I = [
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
@ -101,7 +106,7 @@ _swiss_i = [
0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.584, 0.611, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.584, 0.611, 0.556,
0.556, 0.556, 0.556, 0.500, 0.556, 0.500] 0.556, 0.556, 0.556, 0.500, 0.556, 0.500]
_swiss_bi = [ SWISS_BI = [
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
@ -129,7 +134,7 @@ _swiss_bi = [
0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.584, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.584, 0.611, 0.611,
0.611, 0.611, 0.611, 0.556, 0.611, 0.556] 0.611, 0.611, 0.611, 0.556, 0.611, 0.556]
_roman = [ ROMAN = [
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
@ -157,7 +162,7 @@ _roman = [
0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.564, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.564, 0.500, 0.500,
0.500, 0.500, 0.500, 0.500, 0.500, 0.500] 0.500, 0.500, 0.500, 0.500, 0.500, 0.500]
_roman_b = [ ROMAN_B = [
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
@ -185,7 +190,7 @@ _roman_b = [
0.500, 0.556, 0.500, 0.500, 0.500, 0.500, 0.500, 0.570, 0.500, 0.556, 0.500, 0.556, 0.500, 0.500, 0.500, 0.500, 0.500, 0.570, 0.500, 0.556,
0.556, 0.556, 0.556, 0.500, 0.556, 0.500] 0.556, 0.556, 0.556, 0.500, 0.556, 0.500]
_roman_i = [ ROMAN_I = [
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
@ -213,7 +218,7 @@ _roman_i = [
0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.675, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.675, 0.500, 0.500,
0.500, 0.500, 0.500, 0.444, 0.500, 0.444] 0.500, 0.500, 0.500, 0.444, 0.500, 0.444]
_roman_bi = [ ROMAN_BI = [
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
@ -241,19 +246,22 @@ _roman_bi = [
0.500, 0.556, 0.500, 0.500, 0.500, 0.500, 0.500, 0.570, 0.500, 0.556, 0.500, 0.556, 0.500, 0.500, 0.500, 0.500, 0.500, 0.570, 0.500, 0.556,
0.556, 0.556, 0.556, 0.444, 0.500, 0.444] 0.556, 0.556, 0.556, 0.444, 0.500, 0.444]
_font_array = [ [_swiss, _swiss_b, _swiss_i, _swiss_bi ], FONT_ARRAY = [ [SWISS, SWISS_B, SWISS_I, SWISS_BI ],
[_roman, _roman_b, _roman_i, _roman_bi ] ] [ROMAN, ROMAN_B, ROMAN_I, ROMAN_BI ] ]
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# # string_width
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def string_width(font,text): def string_width(font, text):
"""
returns with width of a string in the specified font
"""
i = font.get_type_face() i = font.get_type_face()
j = font.get_bold() + font.get_italic()*2 j = font.get_bold() + font.get_italic()*2
s = font.get_size() s = font.get_size()
l = _font_array[i][j] l = FONT_ARRAY[i][j]
r = 0 r = 0
for c in text: for c in text:
try: try:
@ -270,7 +278,7 @@ def string_trim(font, text, width, ellipses = "..."):
i = font.get_type_face() i = font.get_type_face()
j = font.get_bold() + font.get_italic()*2 j = font.get_bold() + font.get_italic()*2
s = font.get_size() s = font.get_size()
l = _font_array[i][j] l = FONT_ARRAY[i][j]
ellipses_length = 0 ellipses_length = 0
# get length of each letter # get length of each letter
for c in ellipses: for c in ellipses:

View File

@ -23,15 +23,21 @@
import const import const
def help(target): def help(target):
"""
Display the specified target in a help window. If this fails,
open the manual on the web site.
"""
try: try:
import gnome import gnome
gnome.help_display('gramps',target) gnome.help_display('gramps',target)
except: except:
# FIXME: as manual translations appear online, this needs to
# become more complex to directo to the correct language
url(const.url_manual+'en/') url(const.url_manual+'en/')
def url(target): def url(target):
"""
Open the specified URL in a browser. Attempt using the GNOME system if
available, if not, try to find a browser.
"""
try: try:
import gnome import gnome
gnome.url_show(target) gnome.url_show(target)
@ -40,6 +46,10 @@ def url(target):
def run_browser(url): def run_browser(url):
"""
Attempt of find a browswer, and launch with the browser with the
specified URL
"""
import os import os
search = os.environ['PATH'].split(':') search = os.environ['PATH'].split(':')

View File

@ -379,7 +379,7 @@ class MonitoredEntry:
self.obj.set_editable(not read_only) self.obj.set_editable(not read_only)
if autolist: if autolist:
AutoComp.fill_entry(obj,autolist) AutoComp.fill_entry(obj, autolist)
def reinit(self, set_val, get_val): def reinit(self, set_val, get_val):
self.set_val = set_val self.set_val = set_val
@ -515,7 +515,7 @@ class MonitoredDataType:
default, default,
additional=custom_values) additional=custom_values)
self.sel.set_values((int(get_val()),str(get_val()))) self.sel.set_values((int(get_val()), str(get_val())))
self.obj.set_sensitive(not readonly) self.obj.set_sensitive(not readonly)
self.obj.connect('changed', self.on_change) self.obj.connect('changed', self.on_change)
@ -528,14 +528,14 @@ class MonitoredDataType:
if value[0] == self.get_val().get_custom(): if value[0] == self.get_val().get_custom():
return value return value
else: else:
return (value[0],'') return (value[0], '')
def update(self): def update(self):
val = self.get_val() val = self.get_val()
if type(val) == tuple : if type(val) == tuple :
self.sel.set_values(val) self.sel.set_values(val)
else: else:
self.sel.set_values((int(val),str(val))) self.sel.set_values((int(val), str(val)))
def on_change(self, obj): def on_change(self, obj):
value = self.fix_value(self.sel.get_values()) value = self.fix_value(self.sel.get_values())
@ -567,7 +567,7 @@ class MonitoredMenu:
self.data[v] = index self.data[v] = index
index += 1 index += 1
self.obj.set_model(self.model) self.obj.set_model(self.model)
self.obj.set_active(self.data.get(self.get_val(),0)) self.obj.set_active(self.data.get(self.get_val(), 0))
def on_change(self, obj): def on_change(self, obj):
self.set_val(self.model.get_value(obj.get_active_iter(), 1)) self.set_val(self.model.get_value(obj.get_active_iter(), 1))
@ -643,7 +643,7 @@ class PlaceEntry:
if get_val(): if get_val():
self.set_button(True) self.set_button(True)
p = self.db.get_place_from_handle(self.get_val()) p = self.db.get_place_from_handle(self.get_val())
name = "%s [%s]" % (p.get_title(),p.gramps_id) name = "%s [%s]" % (p.get_title(), p.gramps_id)
else: else:
name = u"" name = u""
self.set_button(False) self.set_button(False)
@ -665,7 +665,7 @@ class PlaceEntry:
obj.set_text(name) obj.set_text(name)
def after_edit(self, place): def after_edit(self, place):
name = "%s [%s]" % (place.get_title(),place.gramps_id) name = "%s [%s]" % (place.get_title(), place.gramps_id)
self.obj.set_text(name) self.obj.set_text(name)
def add_del_clicked(self, obj): def add_del_clicked(self, obj):
@ -692,7 +692,7 @@ class PlaceEntry:
def place_added(self, data): def place_added(self, data):
self.set_val(data.handle) self.set_val(data.handle)
self.obj.set_text("%s [%s]" % (data.get_title(),data.gramps_id)) self.obj.set_text("%s [%s]" % (data.get_title(), data.gramps_id))
self.set_button(True) self.set_button(True)
def share_clicked(self, obj): def share_clicked(self, obj):
@ -721,22 +721,22 @@ class PlaceEntry:
if use_add: if use_add:
image = gtk.Image() image = gtk.Image()
image.set_from_stock(gtk.STOCK_REMOVE,gtk.ICON_SIZE_BUTTON) image.set_from_stock(gtk.STOCK_REMOVE, gtk.ICON_SIZE_BUTTON)
image.show() image.show()
self.add_del.add(image) self.add_del.add(image)
image = gtk.Image() image = gtk.Image()
image.set_from_stock(gtk.STOCK_EDIT,gtk.ICON_SIZE_BUTTON) image.set_from_stock(gtk.STOCK_EDIT, gtk.ICON_SIZE_BUTTON)
image.show() image.show()
self.share.add(image) self.share.add(image)
self.tooltips.set_tip(self.share, _('Edit place')) self.tooltips.set_tip(self.share, _('Edit place'))
self.tooltips.set_tip(self.add_del, _('Remove place')) self.tooltips.set_tip(self.add_del, _('Remove place'))
else: else:
image = gtk.Image() image = gtk.Image()
image.set_from_stock(gtk.STOCK_ADD,gtk.ICON_SIZE_BUTTON) image.set_from_stock(gtk.STOCK_ADD, gtk.ICON_SIZE_BUTTON)
image.show() image.show()
self.add_del.add(image) self.add_del.add(image)
image = gtk.Image() image = gtk.Image()
image.set_from_stock(gtk.STOCK_INDEX,gtk.ICON_SIZE_BUTTON) image.set_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
image.show() image.show()
self.share.add(image) self.share.add(image)
self.tooltips.set_tip(self.share, _('Select an existing place')) self.tooltips.set_tip(self.share, _('Select an existing place'))
@ -942,7 +942,7 @@ class FadeOut(gobject.GObject):
()), ()),
'color-changed': (gobject.SIGNAL_RUN_FIRST, 'color-changed': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, gobject.TYPE_NONE,
(gtk.gdk.Color,)), (gtk.gdk.Color, )),
} }
# How long time it'll take before we start (in ms) # How long time it'll take before we start (in ms)
@ -1034,7 +1034,7 @@ class FadeOut(gobject.GObject):
self._widget.update_background(self._start_color) self._widget.update_background(self._start_color)
self._done = False self._done = False
if gtk.pygtk_version < (2,8,0): if gtk.pygtk_version < (2, 8, 0):
gobject.type_register(FadeOut) gobject.type_register(FadeOut)
class Tooltip(gtk.Window): class Tooltip(gtk.Window):
@ -2271,9 +2271,9 @@ class MaskedEntry(gtk.Entry):
else: else:
values[item] = None values[item] = None
model.append((item,)) model.append((item, ))
if gtk.pygtk_version < (2,8,0): if gtk.pygtk_version < (2, 8, 0):
gobject.type_register(MaskedEntry) gobject.type_register(MaskedEntry)
#number = (int, float, long) #number = (int, float, long)
@ -2298,10 +2298,10 @@ class ValidatableMaskedEntry(MaskedEntry):
()), ()),
'validation-changed': (gobject.SIGNAL_RUN_FIRST, 'validation-changed': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, gobject.TYPE_NONE,
(gobject.TYPE_BOOLEAN,)), (gobject.TYPE_BOOLEAN, )),
'validate': (gobject.SIGNAL_RUN_LAST, 'validate': (gobject.SIGNAL_RUN_LAST,
gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
(gobject.TYPE_PYOBJECT,)), (gobject.TYPE_PYOBJECT, )),
'changed': 'override', 'changed': 'override',
} }
@ -2565,10 +2565,9 @@ class ValidatableMaskedEntry(MaskedEntry):
def _on_fadeout__color_changed(self, fadeout, color): def _on_fadeout__color_changed(self, fadeout, color):
self.update_background(color) self.update_background(color)
if gtk.pygtk_version < (2,8,0): if gtk.pygtk_version < (2, 8, 0):
gobject.type_register(ValidatableMaskedEntry) gobject.type_register(ValidatableMaskedEntry)
def main(args): def main(args):
from DateHandler import parser from DateHandler import parser

View File

@ -51,7 +51,6 @@ LOG = logging.getLogger(".")
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gtk import gtk
import gobject
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -61,7 +60,8 @@ import gobject
from PluginUtils import Plugins, Tool, PluginStatus, \ from PluginUtils import Plugins, Tool, PluginStatus, \
relationship_class, load_plugins, \ relationship_class, load_plugins, \
tool_list, report_list tool_list, report_list
from ReportBase import standalone_categories, report
import ReportBase
import DisplayState import DisplayState
import const import const
import Config import Config
@ -70,8 +70,6 @@ import Errors
import QuestionDialog import QuestionDialog
import PageView import PageView
import Navigation import Navigation
import TipOfDay
import Bookmarks
import RecentFiles import RecentFiles
from BasicUtils import name_displayer from BasicUtils import name_displayer
import GrampsWidgets import GrampsWidgets
@ -189,12 +187,37 @@ UIDEFAULT = '''<ui>
</ui> </ui>
''' '''
#-------------------------------------------------------------------------
#
# ViewManager
#
#-------------------------------------------------------------------------
class ViewManager: class ViewManager:
"""
Overview
========
The ViewManager is the main window of the program. It is closely tied
into the gtk.UIManager to control all menus and actions.
The ViewManager controls the various Views within the GRAMPS programs.
A View is a particular way of looking a information in the GRAMPS main
window. Each view is separate from the others, and has no knowledge of
the others. All Views are held in the DisplayViews module. Examples of
current views include:
- Person View
- Relationship View
- Family View
- Source View
The View Manager does not have to know the number of views, the type of
views, or any other details about the views. It simply provides the
method of containing each view, and switching between the views.s
"""
def __init__(self, state): def __init__(self, state):
"""
Initialize the ViewManager
"""
self.page_is_changing = False self.page_is_changing = False
self.state = state self.state = state
self.active_page = None self.active_page = None
@ -203,11 +226,11 @@ class ViewManager:
self.tips = gtk.Tooltips() self.tips = gtk.Tooltips()
self._key = None self._key = None
self.file_loaded = False self.file_loaded = False
self._build_main_window() self.__build_main_window()
self._connect_signals() self.__connect_signals()
self.do_load_plugins() self.__do_load_plugins()
def _build_main_window(self): def __build_main_window(self):
""" """
Builds the GTK interface Builds the GTK interface
""" """
@ -220,7 +243,7 @@ class ViewManager:
self.statusbar = GrampsWidgets.Statusbar() self.statusbar = GrampsWidgets.Statusbar()
self.RelClass = relationship_class self.rel_class = relationship_class
vbox = gtk.VBox() vbox = gtk.VBox()
self.window.add(vbox) self.window.add(vbox)
@ -240,8 +263,8 @@ class ViewManager:
self.notebook = gtk.Notebook() self.notebook = gtk.Notebook()
self.notebook.set_show_tabs(False) self.notebook.set_show_tabs(False)
self.notebook.show() self.notebook.show()
self._init_lists() self.__init_lists()
self._build_ui_manager() self.__build_ui_manager()
hbox.pack_start(self.notebook, True) hbox.pack_start(self.notebook, True)
self.menubar = self.uimanager.get_widget('/MenuBar') self.menubar = self.uimanager.get_widget('/MenuBar')
@ -250,7 +273,7 @@ class ViewManager:
vbox.pack_start(self.toolbar, False) vbox.pack_start(self.toolbar, False)
vbox.add(hbox) vbox.add(hbox)
self.progress_monitor = ProgressMonitor( self.progress_monitor = ProgressMonitor(
ProgressDialog.GtkProgressDialog, ("",self.window)) ProgressDialog.GtkProgressDialog, ("", self.window))
self.progress = gtk.ProgressBar() self.progress = gtk.ProgressBar()
self.progress.set_size_request(100, -1) self.progress.set_size_request(100, -1)
self.progress.hide() self.progress.hide()
@ -269,29 +292,19 @@ class ViewManager:
self.uistate = DisplayState.DisplayState( self.uistate = DisplayState.DisplayState(
self.window, self.statusbar, self.progress, self.warnbtn, self.window, self.statusbar, self.progress, self.warnbtn,
self.uimanager, self.progress_monitor) self.uimanager, self.progress_monitor)
self.state.connect('database-changed', self.uistate.db_changed) self.state.connect('database-changed', self.uistate.db_changed)
toolbar = self.uimanager.get_widget('/ToolBar')
self.filter_menu = self.uimanager.get_widget( self.filter_menu = self.uimanager.get_widget(
'/MenuBar/ViewMenu/Filter/') '/MenuBar/ViewMenu/Filter/')
openbtn = gtk.MenuToolButton('gramps-db') # handle OPEN button, insert it into the toolbar. Unfortunately,
openbtn.connect('clicked', self.open_activate) # UIManager has no built in support for and Open Recent button
openbtn.set_sensitive(False)
openbtn = self.__build_open_button()
self.uistate.set_open_widget(openbtn) self.uistate.set_open_widget(openbtn)
toolbar.insert(openbtn, 0) self.toolbar.insert(openbtn, 0)
self.open_tips = gtk.Tooltips()
openbtn.set_arrow_tooltip(self.open_tips,
_("Connect to a recent database"),
_("Connect to a recent database"))
openbtn.set_tooltip(self.open_tips,
_("Manage databases"),
_("Manage databases")
)
openbtn.show()
self.person_nav = Navigation.PersonNavigation(self.state, self.uistate) self.person_nav = Navigation.PersonNavigation(self.state, self.uistate)
self._navigation_type[PageView.NAVIGATION_PERSON] = (self.person_nav, self._navigation_type[PageView.NAVIGATION_PERSON] = (self.person_nav,
@ -319,40 +332,63 @@ class ViewManager:
# But we need to realize it here to have gtk.gdk.window handy # But we need to realize it here to have gtk.gdk.window handy
self.window.realize() self.window.realize()
def _connect_signals(self): def __build_open_button(self):
"""
Build the OPEN button. Since GTK's UIManager does not have support for
the Open Recent button, we must build in on our own.
"""
openbtn = gtk.MenuToolButton('gramps-db')
openbtn.connect('clicked', self.__open_activate)
openbtn.set_sensitive(False)
open_tips = gtk.Tooltips()
openbtn.set_arrow_tooltip(
open_tips,
_("Connect to a recent database"),
_("Connect to a recent database"))
openbtn.set_tooltip(
open_tips,
_("Manage databases"),
_("Manage databases")
)
openbtn.show()
return openbtn
def __connect_signals(self):
""" """
connects the signals needed connects the signals needed
""" """
self.window.connect('delete-event', self.quit) self.window.connect('delete-event', self.quit)
self.notebook.connect('switch-page', self.change_page) self.notebook.connect('switch-page', self.change_page)
def _init_lists(self): def __init_lists(self):
self._file_action_list = [ self._file_action_list = [
('FileMenu', None, _('_Family Trees')), ('FileMenu', None, _('_Family Trees')),
('Open', 'gramps-db', _('_Manage Family Trees'), "<control>o", ('Open', 'gramps-db', _('_Manage Family Trees'), "<control>o",
_("Manage databases"), self.open_activate), _("Manage databases"), self.__open_activate),
('OpenRecent', None, _('Open _Recent'), None, ('OpenRecent', None, _('Open _Recent'), None,
_("Open an existing database")), _("Open an existing database")),
('Quit', gtk.STOCK_QUIT, _('_Quit'), "<control>q",None,self.quit), ('Quit', gtk.STOCK_QUIT, _('_Quit'), "<control>q", None,
self.quit),
('ViewMenu', None, _('_View')), ('ViewMenu', None, _('_View')),
('EditMenu', None, _('_Edit')), ('EditMenu', None, _('_Edit')),
('Preferences', gtk.STOCK_PREFERENCES,_('_Preferences'),None, None, ('Preferences', gtk.STOCK_PREFERENCES, _('_Preferences'), None,
self.preferences_activate), None, self.preferences_activate),
('HelpMenu', None, _('_Help')), ('HelpMenu', None, _('_Help')),
('HomePage', None, _('GRAMPS _home page'), None, None, ('HomePage', None, _('GRAMPS _home page'), None, None,
self.home_page_activate), home_page_activate),
('MailingLists', None, _('GRAMPS _mailing lists'), None, None, ('MailingLists', None, _('GRAMPS _mailing lists'), None, None,
self.mailing_lists_activate), mailing_lists_activate),
('ReportBug', None, _('_Report a bug'), None, None, ('ReportBug', None, _('_Report a bug'), None, None,
self.report_bug_activate), report_bug_activate),
('About', gtk.STOCK_ABOUT, _('_About'), None, None, self.about), ('About', gtk.STOCK_ABOUT, _('_About'), None, None,
('PluginStatus', None,_('_Plugin status'), None, None, display_about_box),
('PluginStatus', None, _('_Plugin status'), None, None,
self.plugin_status), self.plugin_status),
('FAQ', None, _('_FAQ'), None, None, self.faq_activate), ('FAQ', None, _('_FAQ'), None, None, faq_activate),
('KeyBindings', None, _('_Key Bindings'), None, None, ('KeyBindings', None, _('_Key Bindings'), None, None, key_bindings),
self.key_bindings),
('UserManual', gtk.STOCK_HELP, _('_User Manual'), 'F1', None, ('UserManual', gtk.STOCK_HELP, _('_User Manual'), 'F1', None,
self.manual_activate), manual_activate),
('TipOfDay', None, _('Tip of the day'), None, None, ('TipOfDay', None, _('Tip of the day'), None, None,
self.tip_of_day_activate), self.tip_of_day_activate),
] ]
@ -369,26 +405,26 @@ class ViewManager:
('GoMenu', None, _('_Go')), ('GoMenu', None, _('_Go')),
('ReportsMenu', None, _('_Reports')), ('ReportsMenu', None, _('_Reports')),
('WindowsMenu', None, _('_Windows')), ('WindowsMenu', None, _('_Windows')),
('F2', None, 'F2', "F2", None, self.keypress), ('F2', None, 'F2', "F2", None, self.__keypress),
('F3', None, 'F3', "F3", None, self.keypress), ('F3', None, 'F3', "F3", None, self.__keypress),
('F4', None, 'F4', "F4", None, self.keypress), ('F4', None, 'F4', "F4", None, self.__keypress),
('F5', None, 'F5', "F5", None, self.keypress), ('F5', None, 'F5', "F5", None, self.__keypress),
('F6', None, 'F6', "F6", None, self.keypress), ('F6', None, 'F6', "F6", None, self.__keypress),
('F7', None, 'F7', "F7", None, self.keypress), ('F7', None, 'F7', "F7", None, self.__keypress),
('F8', None, 'F9', "F8", None, self.keypress), ('F8', None, 'F9', "F8", None, self.__keypress),
('F9', None, 'F9', "F9", None, self.keypress), ('F9', None, 'F9', "F9", None, self.__keypress),
('F11', None, 'F11', "F11", None, self.keypress), ('F11', None, 'F11', "F11", None, self.__keypress),
('<CONTROL>BackSpace', None, '<CONTROL>BackSpace', ('<CONTROL>BackSpace', None, '<CONTROL>BackSpace',
"<CONTROL>BackSpace", None, self.keypress), "<CONTROL>BackSpace", None, self.__keypress),
('<CONTROL>Delete', None, '<CONTROL>Delete', ('<CONTROL>Delete', None, '<CONTROL>Delete',
"<CONTROL>Delete", None, self.keypress), "<CONTROL>Delete", None, self.__keypress),
('<CONTROL>Insert', None, '<CONTROL>Insert', ('<CONTROL>Insert', None, '<CONTROL>Insert',
"<CONTROL>Insert", None, self.keypress), "<CONTROL>Insert", None, self.__keypress),
('F12', None, 'F12', "F12", None, self.keypress), ('F12', None, 'F12', "F12", None, self.__keypress),
('<CONTROL>J', None, '<CONTROL>J', ('<CONTROL>J', None, '<CONTROL>J',
"<CONTROL>J", None, self.keypress), "<CONTROL>J", None, self.__keypress),
('<Alt>N', None, '<Alt>N', "<Alt>N", None, self.next_view), ('<Alt>N', None, '<Alt>N', "<Alt>N", None, self.__next_view),
('<Alt>P', None, '<Alt>P', "<Alt>P", None, self.prev_view), ('<Alt>P', None, '<Alt>P', "<Alt>P", None, self.__prev_view),
] ]
self._action_action_list = [ self._action_action_list = [
@ -410,15 +446,16 @@ class ViewManager:
('Toolbar', None, _('_Toolbar'), None, None, self.toolbar_toggle, ('Toolbar', None, _('_Toolbar'), None, None, self.toolbar_toggle,
self.show_toolbar ), self.show_toolbar ),
('Filter', None, _('_Filter sidebar'), None, None, ('Filter', None, _('_Filter sidebar'), None, None,
self.filter_toggle, self.show_filter), filter_toggle, self.show_filter),
] ]
self._undo_action_list = [ self._undo_action_list = [
('Undo', gtk.STOCK_UNDO, _('_Undo'),'<control>z', None, self.undo), ('Undo', gtk.STOCK_UNDO, _('_Undo'), '<control>z', None,
self.undo),
] ]
self._redo_action_list = [ self._redo_action_list = [
('Redo', gtk.STOCK_REDO,_('_Redo'), '<shift><control>z', None, ('Redo', gtk.STOCK_REDO, _('_Redo'), '<shift><control>z', None,
self.redo), self.redo),
] ]
@ -432,7 +469,12 @@ class ViewManager:
PageView.NAVIGATION_PERSON: (None, None), PageView.NAVIGATION_PERSON: (None, None),
} }
def keypress(self, action): def __keypress(self, action):
"""
Callback that is called on a keypress. It works by extracting the
name of the associated action, and passes that to the active page
(current view) so that it can take the associated action.
"""
name = action.get_name() name = action.get_name()
try: try:
self.active_page.call_function(name) self.active_page.call_function(name)
@ -440,7 +482,12 @@ class ViewManager:
self.uistate.push_message(self.state, self.uistate.push_message(self.state,
_("Key %s is not bound") % name) _("Key %s is not bound") % name)
def next_view(self, action): def __next_view(self, action):
"""
Callback that is called when the next view action is selected.
It selects the next view as the active view. If we reach the end of
the list of views, we wrap around to the first view.
"""
current_page = self.notebook.get_current_page() current_page = self.notebook.get_current_page()
if current_page == len(self.pages)-1: if current_page == len(self.pages)-1:
new_page = 0 new_page = 0
@ -448,7 +495,12 @@ class ViewManager:
new_page = current_page + 1 new_page = current_page + 1
self.buttons[new_page].set_active(True) self.buttons[new_page].set_active(True)
def prev_view(self, action): def __prev_view(self, action):
"""
Callback that is called when the previous view action is selected.
It selects the previous view as the active view. If we reach the beginning
of the list of views, we wrap around to the last view.
"""
current_page = self.notebook.get_current_page() current_page = self.notebook.get_current_page()
if current_page == 0: if current_page == 0:
new_page = len(self.pages)-1 new_page = len(self.pages)-1
@ -457,9 +509,9 @@ class ViewManager:
self.buttons[new_page].set_active(True) self.buttons[new_page].set_active(True)
def init_interface(self): def init_interface(self):
self._init_lists() self.__init_lists()
self.__create_pages()
self.create_pages()
if not self.file_loaded: if not self.file_loaded:
self.actiongroup.set_visible(False) self.actiongroup.set_visible(False)
self.readonlygroup.set_visible(False) self.readonlygroup.set_visible(False)
@ -467,21 +519,21 @@ class ViewManager:
self.build_tools_menu(tool_list) self.build_tools_menu(tool_list)
self.build_report_menu(report_list) self.build_report_menu(report_list)
self.uistate.connect('plugins-reloaded', self.uistate.connect('plugins-reloaded',
self.rebuild_report_and_tool_menus) self.__rebuild_report_and_tool_menus)
self.fileactions.set_sensitive(True) self.fileactions.set_sensitive(True)
self.uistate.widget.set_sensitive(True) self.uistate.widget.set_sensitive(True)
Config.client.notify_add("/apps/gramps/interface/statusbar", Config.client.notify_add("/apps/gramps/interface/statusbar",
self.statusbar_key_update) self.__statusbar_key_update)
Config.client.notify_add("/apps/gramps/interface/filter", Config.client.notify_add("/apps/gramps/interface/filter",
self.filter_signal) self.__filter_signal)
def statusbar_key_update(self, client, cnxn_id, entry, data): def __statusbar_key_update(self, client, cnxn_id, entry, data):
""" """
Callback function for statusbar key update Callback function for statusbar key update
""" """
self.uistate.modify_statusbar(self.state) self.uistate.modify_statusbar(self.state)
def filter_signal(self, client, cnxn_id, entry, data): def __filter_signal(self, client, cnxn_id, entry, data):
""" """
Callback function for statusbar key update Callback function for statusbar key update
""" """
@ -493,15 +545,26 @@ class ViewManager:
# ArgHandler can work without it always shown # ArgHandler can work without it always shown
self.window.show() self.window.show()
if not self.state.db.is_open(): if not self.state.db.is_open():
self.open_activate(None) self.__open_activate(None)
def do_load_plugins(self): def __do_load_plugins(self):
"""
Loads the plugins at initialization time. We load the document
generators and the plugins. The plugin status window is opened
on an error if the user has requested.
"""
# load document generators
self.uistate.status_text(_('Loading document formats...')) self.uistate.status_text(_('Loading document formats...'))
error = load_plugins(const.DOCGEN_DIR) error = load_plugins(const.DOCGEN_DIR)
error |= load_plugins(os.path.join(const.HOME_DIR, "docgen")) error |= load_plugins(os.path.join(const.HOME_DIR, "docgen"))
# load plugins
self.uistate.status_text(_('Loading plugins...')) self.uistate.status_text(_('Loading plugins...'))
error |= load_plugins(const.PLUGINS_DIR) error |= load_plugins(const.PLUGINS_DIR)
error |= load_plugins(os.path.join(const.HOME_DIR, "plugins")) error |= load_plugins(os.path.join(const.HOME_DIR, "plugins"))
# get to ssee if we need to open the plugin status window
if Config.get(Config.POP_PLUGIN_STATUS) and error: if Config.get(Config.POP_PLUGIN_STATUS) and error:
try: try:
PluginStatus.PluginStatus(self.state, self.uistate, []) PluginStatus.PluginStatus(self.state, self.uistate, [])
@ -514,16 +577,24 @@ class ViewManager:
self.uistate.push_message(self.state, _('Ready')) self.uistate.push_message(self.state, _('Ready'))
def quit(self, *obj): def quit(self, *obj):
"""
Closes out the program, backing up data
"""
# mark interface insenstitive to prevent unexpected events
self.uistate.set_sensitive(False) self.uistate.set_sensitive(False)
self.backup()
# backup data, and close the database
self.__backup()
self.state.db.close() self.state.db.close()
# save the current window size
(width, height) = self.window.get_size() (width, height) = self.window.get_size()
Config.set(Config.WIDTH, width) Config.set(Config.WIDTH, width)
Config.set(Config.HEIGHT, height) Config.set(Config.HEIGHT, height)
Config.sync() Config.sync()
gtk.main_quit() gtk.main_quit()
def backup(self): def __backup(self):
""" """
Backup the current file as a backup file. Backup the current file as a backup file.
""" """
@ -564,7 +635,7 @@ class ViewManager:
'number of changes made in the session exceeded the ' 'number of changes made in the session exceeded the '
'limit.')) 'limit.'))
def _build_ui_manager(self): def __build_ui_manager(self):
self.merge_ids = [] self.merge_ids = []
self.uimanager = gtk.UIManager() self.uimanager = gtk.UIManager()
@ -601,12 +672,6 @@ class ViewManager:
self.uimanager.insert_action_group(self.undohistoryactions, 1) self.uimanager.insert_action_group(self.undohistoryactions, 1)
self.uimanager.ensure_update() self.uimanager.ensure_update()
def home_page_activate(self, obj):
GrampsDisplay.url(const.URL_HOMEPAGE)
def mailing_lists_activate(self, obj):
GrampsDisplay.url( const.URL_MAILINGLIST)
def preferences_activate(self, obj): def preferences_activate(self, obj):
try: try:
GrampsCfg.GrampsPreferences(self.uistate, self.state) GrampsCfg.GrampsPreferences(self.uistate, self.state)
@ -615,32 +680,9 @@ class ViewManager:
except Errors.WindowActiveError: except Errors.WindowActiveError:
pass pass
def report_bug_activate(self, obj):
GrampsDisplay.url( const.URL_BUGTRACKER)
def manual_activate(self, obj):
"""Display the GRAMPS manual"""
try:
GrampsDisplay.help('index')
except gobject.GError, msg:
QuestionDialog.ErrorDialog(_("Could not open help"), str(msg))
def faq_activate(self, obj):
"""Display FAQ"""
try:
GrampsDisplay.help('faq')
except gobject.GError, msg:
QuestionDialog.ErrorDialog(_("Could not open help"), str(msg))
def key_bindings(self, obj):
"""Display FAQ"""
try:
GrampsDisplay.help('keybind-lists')
except gobject.GError, msg:
QuestionDialog.ErrorDialog(_("Could not open help"), str(msg))
def tip_of_day_activate(self, obj): def tip_of_day_activate(self, obj):
"""Display Tip of the day""" """Display Tip of the day"""
import TipOfDay
TipOfDay.TipOfDay(self.uistate) TipOfDay.TipOfDay(self.uistate)
def plugin_status(self, obj): def plugin_status(self, obj):
@ -653,41 +695,6 @@ class ViewManager:
old_win.close() old_win.close()
PluginStatus.PluginStatus(self.state, self.uistate, []) PluginStatus.PluginStatus(self.state, self.uistate, [])
def about(self, obj):
about = gtk.AboutDialog()
about.set_name(const.PROGRAM_NAME)
about.set_version(const.VERSION)
about.set_copyright(const.COPYRIGHT_MSG)
about.set_artists([
_("Much of GRAMPS' artwork is either from\n"
"the Tango Project or derived from the Tango\n"
"Project. This artwork is released under the\n"
"Create Commons Attribution-ShareAlike 2.5\n"
"license.")
])
try:
ifile = open(const.LICENSE_FILE, "r")
about.set_license(ifile.read().replace('\x0c', ''))
ifile.close()
except:
about.set_license("License file is missing")
about.set_comments(_(const.COMMENTS))
about.set_website_label(_('GRAMPS Homepage'))
about.set_website(const.URL_HOMEPAGE)
about.set_authors(const.AUTHORS)
# Only set translation credits if they are translated
trans_credits = _(const.TRANSLATORS)
if trans_credits != const.TRANSLATORS:
about.set_translator_credits(trans_credits)
about.set_documenters(const.DOCUMENTERS)
about.set_logo(gtk.gdk.pixbuf_new_from_file(const.SPLASH))
about.set_modal(True)
about.show()
about.run()
about.destroy()
def sidebar_toggle(self, obj): def sidebar_toggle(self, obj):
if obj.get_active(): if obj.get_active():
self.ebox.show() self.ebox.show()
@ -708,29 +715,34 @@ class ViewManager:
Config.set(Config.TOOLBAR_ON, False) Config.set(Config.TOOLBAR_ON, False)
Config.sync() Config.sync()
def filter_toggle(self, obj):
Config.set(Config.FILTER, obj.get_active())
Config.sync()
def register_view(self, view): def register_view(self, view):
self.views.append(view) self.views.append(view)
def switch_page_on_dnd(self, widget, context, x, y, time, page_no): def __switch_page_on_dnd(self, widget, context, x, y, time, page_no):
self.vb_handlers_block() self.vb_handlers_block()
if self.notebook.get_current_page() != page_no: if self.notebook.get_current_page() != page_no:
self.notebook.set_current_page(page_no) self.notebook.set_current_page(page_no)
self.vb_handlers_unblock() self.vb_handlers_unblock()
def create_pages(self): def __setup_text_tips(self, use_text):
self.pages = [] """
self.prev_nav = PageView.NAVIGATION_NONE Enable/disable the text tips in the sidebar
"""
use_text = Config.get(Config.SIDEBAR_TEXT)
if use_text: if use_text:
self.tips.disable() self.tips.disable()
else: else:
self.tips.enable() self.tips.enable()
def __create_pages(self):
"""
Creates the Views
"""
self.pages = []
self.prev_nav = PageView.NAVIGATION_NONE
use_text = Config.get(Config.SIDEBAR_TEXT)
self.__setup_text_tips(use_text)
index = 0 index = 0
for page_def in self.views: for page_def in self.views:
page = page_def(self.state, self.uistate) page = page_def(self.state, self.uistate)
@ -755,41 +767,19 @@ class ViewManager:
# Enable view switching during DnD # Enable view switching during DnD
hbox.drag_dest_set(0, [], 0) hbox.drag_dest_set(0, [], 0)
hbox.connect('drag_motion', self.switch_page_on_dnd, page_no) hbox.connect('drag_motion', self.__switch_page_on_dnd, page_no)
# create the button and add it to the sidebar # create the button and add it to the sidebar
button = gtk.ToggleButton() button = self.__make_sidebar_button(use_text, index,
self.tips.set_tip(button, page_title) page_title, page_stock)
hbox = gtk.HBox()
hbox.show()
image = gtk.Image()
if use_text:
image.set_from_stock(page_stock, gtk.ICON_SIZE_BUTTON)
else:
image.set_from_stock(page_stock, gtk.ICON_SIZE_DND)
image.show()
hbox.pack_start(image, False, False)
hbox.set_spacing(4)
if use_text:
label = gtk.Label(page_title)
label.show()
hbox.pack_start(label, False, True)
button.add(hbox)
button.set_relief(gtk.RELIEF_NONE)
button.set_alignment(0, 0.5)
handler_id = button.connect('clicked', self.vb_clicked, index)
button.show()
index += 1 index += 1
self.bbox.pack_start(button, False) self.bbox.pack_start(button, False)
self.buttons.append(button) self.buttons.append(button)
self.button_handlers.append(handler_id)
# Enable view switching during DnD # Enable view switching during DnD
button.drag_dest_set(0, [], 0) button.drag_dest_set(0, [], 0)
button.connect('drag_motion', self.switch_page_on_dnd, page_no) button.connect('drag_motion', self.__switch_page_on_dnd, page_no)
use_current = Config.get(Config.USE_LAST_VIEW) use_current = Config.get(Config.USE_LAST_VIEW)
if use_current: if use_current:
@ -804,7 +794,48 @@ class ViewManager:
self.active_page.set_active() self.active_page.set_active()
self.notebook.set_current_page(current_page) self.notebook.set_current_page(current_page)
def vb_clicked(self, button, index): def __make_sidebar_button(self, use_text, index, page_title, page_stock):
"""
Creates the sidebar button. The page_title is the text associated with
the button.
"""
# create the button
button = gtk.ToggleButton()
button.set_relief(gtk.RELIEF_NONE)
button.set_alignment(0, 0.5)
# add the tooltip
self.tips.set_tip(button, page_title)
# connect the signal, along with the index as user data
handler_id = button.connect('clicked', self.__vb_clicked, index)
self.button_handlers.append(handler_id)
button.show()
# add the image. If we are using text, use the BUTTON (larger) size.
# otherwise, use the smaller size
hbox = gtk.HBox()
hbox.show()
image = gtk.Image()
if use_text:
image.set_from_stock(page_stock, gtk.ICON_SIZE_BUTTON)
else:
image.set_from_stock(page_stock, gtk.ICON_SIZE_DND)
image.show()
hbox.pack_start(image, False, False)
hbox.set_spacing(4)
# add text if requested
if use_text:
label = gtk.Label(page_title)
label.show()
hbox.pack_start(label, False, True)
button.add(hbox)
return button
def __vb_clicked(self, button, index):
if Config.get(Config.VIEW): if Config.get(Config.VIEW):
self.vb_handlers_block() self.vb_handlers_block()
self.notebook.set_current_page(index) self.notebook.set_current_page(index)
@ -894,14 +925,14 @@ class ViewManager:
def import_pkg(self, filename): def import_pkg(self, filename):
import ReadPkg import ReadPkg
ReadPkg.impData(self.state.db, filename, self.uistate.pulse_progressbar) ReadPkg.impData(self.state.db, filename, self.uistate.pulse_progressbar)
self.post_load() self.__post_load()
def import_data(self, obj): def import_data(self, obj):
if self.state.db.is_open(): if self.state.db.is_open():
self.db_loader.import_file() self.db_loader.import_file()
self.post_load() self.__post_load()
def open_activate(self, obj): def __open_activate(self, obj):
import DbManager import DbManager
dialog = DbManager.DbManager(self.state, self.window) dialog = DbManager.DbManager(self.state, self.window)
value = dialog.run() value = dialog.run()
@ -912,7 +943,7 @@ class ViewManager:
os.chdir(os.path.dirname(filename)) os.chdir(os.path.dirname(filename))
except: except:
pass pass
self.post_load_newdb(filename, 'x-directory/normal', title) self.__post_load_newdb(filename, 'x-directory/normal', title)
def read_file(self, filename, filetype): def read_file(self, filename, filetype):
""" """
@ -980,14 +1011,10 @@ class ViewManager:
def save_as_activate(self, obj): def save_as_activate(self, obj):
if self.state.db.is_open(): if self.state.db.is_open():
(filename, filetype) = self.db_loader.save_as() (filename, filetype) = self.db_loader.save_as()
self.post_load_newdb(filename, filetype) self.__post_load_newdb(filename, filetype)
def new_activate(self, obj):
(filename, filetype) = self.db_loader.new_file()
self.post_load_newdb(filename, filetype)
def read_recent_file(self, filename, filetype): def read_recent_file(self, filename, filetype):
if self.db_loader.read_file(filename,'x-directory/normal'): if self.db_loader.read_file(filename, 'x-directory/normal'):
# Attempt to figure out the database title # Attempt to figure out the database title
path = os.path.join(filename, "name.txt") path = os.path.join(filename, "name.txt")
@ -998,9 +1025,9 @@ class ViewManager:
except: except:
title = filename title = filename
self.post_load_newdb(filename, 'x-directory/normal', title) self.__post_load_newdb(filename, 'x-directory/normal', title)
def post_load(self): def __post_load(self):
# This method is for the common UI post_load, both new files # This method is for the common UI post_load, both new files
# and added data like imports. # and added data like imports.
if self.state.active : if self.state.active :
@ -1019,7 +1046,7 @@ class ViewManager:
self.uistate.window.window.set_cursor(None) self.uistate.window.window.set_cursor(None)
def post_load_newdb(self, filename, filetype, title=None): def __post_load_newdb(self, filename, filetype, title=None):
if not filename: if not filename:
return return
@ -1027,8 +1054,6 @@ class ViewManager:
# This method is for UI stuff when the database has changed. # This method is for UI stuff when the database has changed.
# Window title, recent files, etc related to new file. # Window title, recent files, etc related to new file.
check_for_portability_problems(filetype)
self.state.db.set_save_path(filename) self.state.db.set_save_path(filename)
# Update window title # Update window title
@ -1079,15 +1104,15 @@ class ViewManager:
RecentFiles.recent_files(filename, name) RecentFiles.recent_files(filename, name)
self.recent_manager.build() self.recent_manager.build()
# Call common post_load # Call common __post_load
self.post_load() self.__post_load()
def change_undo_label(self, label): def change_undo_label(self, label):
self.uimanager.remove_action_group(self.undoactions) self.uimanager.remove_action_group(self.undoactions)
self.undoactions = gtk.ActionGroup('Undo') self.undoactions = gtk.ActionGroup('Undo')
if label: if label:
self.undoactions.add_actions([ self.undoactions.add_actions([
('Undo', gtk.STOCK_UNDO,label, '<control>z', None, self.undo)]) ('Undo', gtk.STOCK_UNDO, label, '<control>z', None, self.undo)])
else: else:
self.undoactions.add_actions([ self.undoactions.add_actions([
('Undo', gtk.STOCK_UNDO, _('_Undo'), ('Undo', gtk.STOCK_UNDO, _('_Undo'),
@ -1132,8 +1157,13 @@ class ViewManager:
pass pass
def setup_bookmarks(self): def setup_bookmarks(self):
self.bookmarks = Bookmarks.Bookmarks(self.state, self.uistate, """
self.state.db.get_bookmarks()) Initializes the bookmarks based of the database. This needs to
be called anytime the database changes.
"""
import Bookmarks
self.bookmarks = Bookmarks.Bookmarks(
self.state, self.uistate, self.state.db.get_bookmarks())
def add_bookmark(self, obj): def add_bookmark(self, obj):
if self.state.active: if self.state.active:
@ -1184,7 +1214,7 @@ class ViewManager:
self.undo_history_window = UndoHistory.UndoHistory(self.state, self.undo_history_window = UndoHistory.UndoHistory(self.state,
self.uistate) self.uistate)
except Errors.WindowActiveError: except Errors.WindowActiveError:
pass return
def export_data(self, obj): def export_data(self, obj):
if self.state.db.db_is_open: if self.state.db.db_is_open:
@ -1194,8 +1224,7 @@ class ViewManager:
except Errors.WindowActiveError: except Errors.WindowActiveError:
return return
def __rebuild_report_and_tool_menus(self, tool_list, report_list):
def rebuild_report_and_tool_menus(self, tool_list, report_list):
self.build_tools_menu(tool_list) self.build_tools_menu(tool_list)
self.build_report_menu(report_list) self.build_report_menu(report_list)
@ -1211,7 +1240,7 @@ class ViewManager:
def build_report_menu(self, report_list): def build_report_menu(self, report_list):
self.reportactions = gtk.ActionGroup('ReportWindow') self.reportactions = gtk.ActionGroup('ReportWindow')
(ui, actions) = self.build_plugin_menu( (ui, actions) = self.build_plugin_menu(
'ReportsMenu', report_list, standalone_categories, 'ReportsMenu', report_list, ReportBase.standalone_categories,
make_report_callback) make_report_callback)
self.reportactions.add_actions(actions) self.reportactions.add_actions(actions)
self.uistate.uimanager.add_ui_from_string(ui) self.uistate.uimanager.add_ui_from_string(ui)
@ -1274,41 +1303,94 @@ class ViewManager:
ofile.write('</menu></menubar></ui>') ofile.write('</menu></menubar></ui>')
return (ofile.getvalue(), actions) return (ofile.getvalue(), actions)
def display_about_box(obj):
"""
Displays the About box.
"""
about = gtk.AboutDialog()
about.set_name(const.PROGRAM_NAME)
about.set_version(const.VERSION)
about.set_copyright(const.COPYRIGHT_MSG)
about.set_artists([
_("Much of GRAMPS' artwork is either from\n"
"the Tango Project or derived from the Tango\n"
"Project. This artwork is released under the\n"
"Create Commons Attribution-ShareAlike 2.5\n"
"license.")
])
try:
ifile = open(const.LICENSE_FILE, "r")
about.set_license(ifile.read().replace('\x0c', ''))
ifile.close()
except:
about.set_license("License file is missing")
about.set_comments(_(const.COMMENTS))
about.set_website_label(_('GRAMPS Homepage'))
about.set_website(const.URL_HOMEPAGE)
about.set_authors(const.AUTHORS)
# Only set translation credits if they are translated
trans_credits = _(const.TRANSLATORS)
if trans_credits != const.TRANSLATORS:
about.set_translator_credits(trans_credits)
about.set_documenters(const.DOCUMENTERS)
about.set_logo(gtk.gdk.pixbuf_new_from_file(const.SPLASH))
about.set_modal(True)
about.show()
about.run()
about.destroy()
def filter_toggle(obj):
"""
Save the filter state to the config settings on change
"""
Config.set(Config.FILTER, obj.get_active())
Config.sync()
def key_bindings(obj):
"""
Display key bindings
"""
GrampsDisplay.help('keybind-lists')
def manual_activate(self, obj):
"""
Display the GRAMPS manual
"""
GrampsDisplay.help('index')
def report_bug_activate(obj):
"""
Display the bug tracker web site
"""
GrampsDisplay.url(const.URL_BUGTRACKER)
def home_page_activate(obj):
"""
Display the GRAMPS home page
"""
GrampsDisplay.url(const.URL_HOMEPAGE)
def mailing_lists_activate(obj):
"""
Display the mailing list web page
"""
GrampsDisplay.url( const.URL_MAILINGLIST)
def faq_activate(obj):
"""Display FAQ"""
GrampsDisplay.help('faq')
def by_menu_name(first, second): def by_menu_name(first, second):
return cmp(first[2], second[2]) return cmp(first[2], second[2])
def make_report_callback(lst, dbstate, uistate): def make_report_callback(lst, dbstate, uistate):
return lambda x: report(dbstate, uistate, dbstate.get_active_person(), return lambda x: ReportBase.report(
dbstate, uistate, dbstate.get_active_person(),
lst[0], lst[1], lst[2], lst[3], lst[4], lst[5]) lst[0], lst[1], lst[2], lst[3], lst[4], lst[5])
def make_tool_callback(lst, dbstate, uistate): def make_tool_callback(lst, dbstate, uistate):
return lambda x: Tool.gui_tool(dbstate, uistate, return lambda x: Tool.gui_tool(dbstate, uistate,
lst[0], lst[1], lst[2], lst[3], lst[4], lst[0], lst[1], lst[2], lst[3], lst[4],
dbstate.db.request_rebuild) dbstate.db.request_rebuild)
def check_for_portability_problems(filetype):
"""
Checks for the portability problem caused by the combination of
python 2.4 and bsddb. If the problem exists, issue a warning message
that the user can disable.
"""
# check for a GRDB type and if transactions are enabled. If not,
# then we do not have any issues
if filetype == const.APP_GRAMPS and Config.get(Config.TRANSACTIONS):
import sys
# Check for a version less than python 2.5. This is held in the
# sys.version_info variable
version = (sys.version_info[0], sys.version_info[1])
if version < (2, 5) and not Config.get(Config.PORT_WARN):
QuestionDialog.MessageHideDialog(
_('Family Tree is not portable'),
_('If you need to transfer the database to another machine, '
'export to a GRAMPS Package, and import the GRAMPS Package '
'on the other machine.'),
Config.PORT_WARN)