222 lines
7.8 KiB
Python
222 lines
7.8 KiB
Python
|
#
|
||
|
# Gramps - a GTK+/GNOME based genealogy program
|
||
|
#
|
||
|
# Copyright (C) 2009 Gerald Britton <gerald.britton@gmail.com>
|
||
|
#
|
||
|
# 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: glade.py 10874 2009-03-03 18:00:00Z gbritton $
|
||
|
|
||
|
#------------------------------------------------------------------------
|
||
|
#
|
||
|
# Glade
|
||
|
#
|
||
|
#------------------------------------------------------------------------
|
||
|
|
||
|
"""
|
||
|
Glade file operations
|
||
|
|
||
|
This module exports the Glade class.
|
||
|
|
||
|
"""
|
||
|
|
||
|
#------------------------------------------------------------------------
|
||
|
#
|
||
|
# Python modules
|
||
|
#
|
||
|
#------------------------------------------------------------------------
|
||
|
import sys
|
||
|
import os
|
||
|
import gtk
|
||
|
|
||
|
#------------------------------------------------------------------------
|
||
|
#
|
||
|
# gramps modules
|
||
|
#
|
||
|
#------------------------------------------------------------------------
|
||
|
import const
|
||
|
|
||
|
#------------------------------------------------------------------------
|
||
|
#
|
||
|
# Glade class. Derived from gtk.Builder
|
||
|
#
|
||
|
#------------------------------------------------------------------------
|
||
|
|
||
|
class Glade(gtk.Builder):
|
||
|
"""
|
||
|
Glade class: Manage glade files as gtk.Builder objects
|
||
|
"""
|
||
|
__slots__ = ['__toplevel', '__filename', '__dirname']
|
||
|
|
||
|
def __init__(self, filename=None, dirname=None, toplevel=None):
|
||
|
"""
|
||
|
Class Constructor: Returns a new instance of the Glade class
|
||
|
|
||
|
@type filename: string
|
||
|
@param filename: The name of the glade file to be used. Defaults to None
|
||
|
@type dirname: string
|
||
|
@param dirname: The directory to search for the glade file. Defaults to
|
||
|
None which will cause a search for the file in the default
|
||
|
directory followed by the directory of the calling module.
|
||
|
@type toplevel: toplevel
|
||
|
@param toplevel: The toplevel object to search for in the glade file.
|
||
|
Defaults to None, which will cause a search for a toplevel
|
||
|
matching the file name.
|
||
|
@rtype: object reference
|
||
|
@return: reference to the newly-created Glade instance
|
||
|
"""
|
||
|
gtk.Builder.__init__(self)
|
||
|
|
||
|
if isinstance(toplevel, gtk.Container): # if we have a Gtk object
|
||
|
self.__toplevel = toplevel # just remember it
|
||
|
return # and we're done
|
||
|
|
||
|
filename_given = filename is not None
|
||
|
dirname_given = dirname is not None
|
||
|
|
||
|
# if filename not given, use module name to derive it
|
||
|
|
||
|
if not filename:
|
||
|
filename = sys._getframe(1).f_code.co_filename
|
||
|
filename = os.path.basename(filename)
|
||
|
filename = filename.rpartition('.')[0] + '.glade'
|
||
|
filename = filename.lstrip('_').lower()
|
||
|
|
||
|
# if dirname not given, use current directory
|
||
|
|
||
|
if not dirname:
|
||
|
dirname = sys._getframe(1).f_code.co_filename
|
||
|
dirname = os.path.dirname(dirname)
|
||
|
|
||
|
# try to find the glade file
|
||
|
|
||
|
if filename_given and dirname_given: # both given -- use them
|
||
|
path = os.path.join(dirname, filename)
|
||
|
|
||
|
elif filename_given: # try default directory first
|
||
|
path = os.path.join(const.GLADE_DIR, filename)
|
||
|
if not os.path.exists(path): # then module directory
|
||
|
path = os.path.join(dirname, filename)
|
||
|
|
||
|
elif dirname_given: # dirname given -- use it
|
||
|
path = os.path.join(dirname, filename)
|
||
|
|
||
|
# neither filename nor dirname given. Try:
|
||
|
# 1. derived filename in default directory
|
||
|
# 2. derived filename in module directory
|
||
|
|
||
|
else:
|
||
|
path = os.path.join(const.GLADE_DIR, filename)
|
||
|
if not os.path.exists(path):
|
||
|
path = os.path.join(dirname, filename)
|
||
|
|
||
|
# try to build Gtk objects from glade file. Let exceptions happen
|
||
|
|
||
|
self.add_from_file(path)
|
||
|
self.__filename, self.__dirname = os.path.split(path)
|
||
|
|
||
|
# try to find the toplevel widget
|
||
|
|
||
|
if toplevel: # toplevel is given
|
||
|
self.__toplevel = self.get_object(toplevel)
|
||
|
else: # toplevel not given
|
||
|
# first, use filename as possible toplevel widget name
|
||
|
self.__toplevel = self.get_object(filename.rpartition('.')[0])
|
||
|
|
||
|
# next try lowercase filename as possible widget name
|
||
|
if not self.__toplevel:
|
||
|
self.__toplevel = self.get_object(
|
||
|
filename.rpartition('.')[0].lower())
|
||
|
|
||
|
if not self.__toplevel:
|
||
|
# if no match found, search for first toplevel widget
|
||
|
for obj in self.get_objects():
|
||
|
if hasattr(obj, 'get_toplevel'):
|
||
|
self.__toplevel = obj.get_toplevel()
|
||
|
break
|
||
|
else:
|
||
|
self.__toplevel = None
|
||
|
|
||
|
def __get_filename(self):
|
||
|
"""
|
||
|
__get_filename: return filename of glade file
|
||
|
@rtype: string
|
||
|
@return: filename of glade file
|
||
|
"""
|
||
|
return self.__filename
|
||
|
|
||
|
filename = property(__get_filename)
|
||
|
|
||
|
def __get_dirname(self):
|
||
|
"""
|
||
|
__get_dirname: return directory where glade file found
|
||
|
@rtype: string
|
||
|
@return: directory where glade file found
|
||
|
"""
|
||
|
return self.__dirname
|
||
|
|
||
|
dirname = property(__get_dirname)
|
||
|
|
||
|
def __get_toplevel(self):
|
||
|
"""
|
||
|
__get_toplevel: return toplevel object
|
||
|
@rtype: object
|
||
|
@return: toplevel object
|
||
|
"""
|
||
|
return self.__toplevel
|
||
|
|
||
|
def __set_toplevel(self, toplevel):
|
||
|
"""
|
||
|
__set_toplevel: set toplevel object
|
||
|
|
||
|
@type toplevel: string
|
||
|
@param toplevel: The name of the toplevel object to use
|
||
|
"""
|
||
|
self.__toplevel = self.get_object(toplevel)
|
||
|
|
||
|
toplevel = property(__get_toplevel, __set_toplevel)
|
||
|
|
||
|
def get_child_object(self, value, toplevel=None):
|
||
|
"""
|
||
|
get_child_object: search for a child object, by name, within a given
|
||
|
toplevel. If no toplevel argument is supplied, use
|
||
|
the toplevel attribute for this instance
|
||
|
@type value: string
|
||
|
@param value: The name of the child object to find
|
||
|
@type toplevel: string
|
||
|
@param toplevel: The name of the toplevel object to us
|
||
|
@rtype: object
|
||
|
@return: child object
|
||
|
"""
|
||
|
|
||
|
if not toplevel:
|
||
|
toplevel = self.__toplevel
|
||
|
if not toplevel:
|
||
|
raise ValueError, "Top level object required"
|
||
|
|
||
|
if isinstance(toplevel, basestring):
|
||
|
toplevel = self.get_object(toplevel)
|
||
|
|
||
|
queue = [toplevel]
|
||
|
while queue:
|
||
|
obj = queue.pop(0)
|
||
|
if obj.get_name() == value:
|
||
|
return obj
|
||
|
if hasattr(obj, 'get_children'):
|
||
|
queue += obj.get_children()
|
||
|
else:
|
||
|
return None
|