2011-01-11 06:51:38 +05:30
|
|
|
#
|
|
|
|
# Gramps - a GTK+/GNOME based genealogy program
|
|
|
|
#
|
2011-01-30 08:32:38 +05:30
|
|
|
# Copyright (C) 2000-2007 Donald N. Allingham
|
|
|
|
# Copyright (C) 2011 Nick Hall
|
2011-02-03 03:27:27 +05:30
|
|
|
# Copyright (C) 2011 Gary Burton
|
2011-01-11 06:51:38 +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$
|
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
"""
|
|
|
|
Module that implements the sidebar and bottombar fuctionality.
|
|
|
|
"""
|
2011-01-11 06:51:38 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Python modules
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
from gen.ggettext import gettext as _
|
2011-01-30 08:32:38 +05:30
|
|
|
import time
|
|
|
|
import os
|
2011-01-11 06:51:38 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# GNOME modules
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
import gtk
|
2011-01-30 08:32:38 +05:30
|
|
|
gtk.rc_parse_string("""
|
|
|
|
style "tab-button-style" {
|
|
|
|
GtkWidget::focus-padding = 0
|
|
|
|
GtkWidget::focus-line-width = 0
|
|
|
|
xthickness = 0
|
|
|
|
ythickness = 0
|
|
|
|
}
|
|
|
|
widget "*.tab-button" style "tab-button-style"
|
|
|
|
""")
|
2011-01-11 06:51:38 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Gramps modules
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
import ConfigParser
|
|
|
|
import const
|
2011-01-30 08:32:38 +05:30
|
|
|
import ManagedWindow
|
|
|
|
import GrampsDisplay
|
2011-01-11 06:51:38 +05:30
|
|
|
from gui.widgets.grampletpane import (AVAILABLE_GRAMPLETS,
|
|
|
|
GET_AVAILABLE_GRAMPLETS,
|
|
|
|
get_gramplet_opts,
|
|
|
|
get_gramplet_options_by_name,
|
2011-01-30 08:32:38 +05:30
|
|
|
make_requested_gramplet,
|
|
|
|
GuiGramplet)
|
|
|
|
from gui.widgets.undoablebuffer import UndoableBuffer
|
2011-01-11 06:51:38 +05:30
|
|
|
from ListModel import ListModel, NOSORT
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Constants
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2011-01-30 08:32:38 +05:30
|
|
|
WIKI_HELP_PAGE = const.URL_MANUAL_PAGE + '_-_Gramplets'
|
2011-01-11 06:51:38 +05:30
|
|
|
NL = "\n"
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
2011-01-19 20:10:39 +05:30
|
|
|
# GrampsBar class
|
2011-01-11 06:51:38 +05:30
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2011-01-30 08:32:38 +05:30
|
|
|
class GrampsBar(gtk.Notebook):
|
2011-01-11 06:51:38 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
A class which defines the graphical representation of the GrampsBar.
|
2011-01-11 06:51:38 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
def __init__(self, dbstate, uistate, pageview, configfile, defaults):
|
|
|
|
gtk.Notebook.__init__(self)
|
2011-01-11 06:51:38 +05:30
|
|
|
|
|
|
|
self.dbstate = dbstate
|
2011-01-30 08:32:38 +05:30
|
|
|
self.uistate = uistate
|
|
|
|
self.pageview = pageview
|
2011-01-11 06:51:38 +05:30
|
|
|
self.configfile = os.path.join(const.VERSION_DIR, "%s.ini" % configfile)
|
2011-01-30 08:32:38 +05:30
|
|
|
self.detached_gramplets = []
|
2011-02-02 23:02:13 +05:30
|
|
|
self.empty = False
|
2011-01-11 06:51:38 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
self.set_group_id(1)
|
|
|
|
self.set_show_border(False)
|
|
|
|
self.set_scrollable(True)
|
|
|
|
self.connect('switch-page', self.__switch_page)
|
|
|
|
self.connect('page-added', self.__page_added)
|
2011-02-02 23:02:13 +05:30
|
|
|
self.connect('page-removed', self.__page_removed)
|
2011-01-30 08:32:38 +05:30
|
|
|
self.connect('create-window', self.__create_window)
|
|
|
|
self.connect('button-press-event', self.__button_press)
|
2011-01-11 06:51:38 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
config_settings, opts_list = self.__load(defaults)
|
2011-01-11 06:51:38 +05:30
|
|
|
|
2011-01-19 20:10:39 +05:30
|
|
|
opts_list.sort(key=lambda opt: opt["page"])
|
|
|
|
for opts in opts_list:
|
2011-01-30 08:32:38 +05:30
|
|
|
all_opts = get_gramplet_opts(opts["name"], opts)
|
|
|
|
gramplet = make_requested_gramplet(TabGramplet, self, all_opts,
|
2011-01-19 20:10:39 +05:30
|
|
|
self.dbstate, self.uistate)
|
|
|
|
self.__add_tab(gramplet)
|
|
|
|
|
2011-02-02 23:02:13 +05:30
|
|
|
if len(opts_list) == 0:
|
|
|
|
self.empty = True
|
|
|
|
self.__create_empty_tab()
|
|
|
|
|
2011-01-19 20:10:39 +05:30
|
|
|
if config_settings[0]:
|
2011-01-30 08:32:38 +05:30
|
|
|
self.show()
|
|
|
|
self.set_current_page(config_settings[1])
|
2011-01-19 20:10:39 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def __load(self, defaults):
|
2011-01-11 06:51:38 +05:30
|
|
|
"""
|
|
|
|
Load the gramplets from the configuration file.
|
|
|
|
"""
|
|
|
|
retval = []
|
|
|
|
visible = False
|
|
|
|
default_page = 0
|
|
|
|
filename = self.configfile
|
|
|
|
if filename and os.path.exists(filename):
|
|
|
|
cp = ConfigParser.ConfigParser()
|
|
|
|
cp.read(filename)
|
|
|
|
for sec in cp.sections():
|
|
|
|
if sec == "Bar Options":
|
|
|
|
if "visible" in cp.options(sec):
|
|
|
|
visible = cp.get(sec, "visible") == "True"
|
|
|
|
if "page" in cp.options(sec):
|
|
|
|
default_page = int(cp.get(sec, "page"))
|
|
|
|
else:
|
|
|
|
data = {"title": sec}
|
|
|
|
for opt in cp.options(sec):
|
|
|
|
if opt.startswith("data["):
|
|
|
|
temp = data.get("data", {})
|
|
|
|
#temp.append(cp.get(sec, opt).strip())
|
|
|
|
pos = int(opt[5:-1])
|
|
|
|
temp[pos] = cp.get(sec, opt).strip()
|
|
|
|
data["data"] = temp
|
|
|
|
else:
|
|
|
|
data[opt] = cp.get(sec, opt).strip()
|
|
|
|
if "data" in data:
|
|
|
|
data["data"] = [data["data"][key]
|
|
|
|
for key in sorted(data["data"].keys())]
|
|
|
|
if "name" not in data:
|
|
|
|
data["name"] = "Unnamed Gramplet"
|
2011-01-30 08:32:38 +05:30
|
|
|
data["tname"] = _("Unnamed Gramplet")
|
2011-01-19 20:10:39 +05:30
|
|
|
retval.append(data)
|
2011-01-11 06:51:38 +05:30
|
|
|
else:
|
|
|
|
# give defaults as currently known
|
2011-01-30 08:32:38 +05:30
|
|
|
for name in defaults:
|
2011-01-11 06:51:38 +05:30
|
|
|
if name in AVAILABLE_GRAMPLETS():
|
2011-01-19 20:10:39 +05:30
|
|
|
retval.append(GET_AVAILABLE_GRAMPLETS(name))
|
2011-01-11 06:51:38 +05:30
|
|
|
return ((visible, default_page), retval)
|
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def __save(self):
|
2011-01-11 06:51:38 +05:30
|
|
|
"""
|
|
|
|
Save the gramplet configuration.
|
|
|
|
"""
|
|
|
|
filename = self.configfile
|
|
|
|
try:
|
|
|
|
fp = open(filename, "w")
|
2011-01-30 08:32:38 +05:30
|
|
|
except IOError:
|
2011-01-11 06:51:38 +05:30
|
|
|
print "Failed writing '%s'; gramplets not saved" % filename
|
|
|
|
return
|
|
|
|
fp.write(";; Gramps bar configuration file" + NL)
|
|
|
|
fp.write((";; Automatically created at %s" %
|
|
|
|
time.strftime("%Y/%m/%d %H:%M:%S")) + NL + NL)
|
|
|
|
fp.write("[Bar Options]" + NL)
|
2011-01-30 08:32:38 +05:30
|
|
|
fp.write(("visible=%s" + NL) % self.get_property('visible'))
|
|
|
|
fp.write(("page=%d" + NL) % self.get_current_page())
|
2011-01-11 06:51:38 +05:30
|
|
|
fp.write(NL)
|
|
|
|
|
2011-02-02 23:02:13 +05:30
|
|
|
if self.empty:
|
|
|
|
gramplet_list = []
|
|
|
|
else:
|
|
|
|
gramplet_list = [self.get_nth_page(page_num)
|
|
|
|
for page_num in range(self.get_n_pages())]
|
2011-01-30 08:32:38 +05:30
|
|
|
|
|
|
|
for page_num, gramplet in enumerate(gramplet_list):
|
|
|
|
opts = get_gramplet_options_by_name(gramplet.gname)
|
2011-01-11 06:51:38 +05:30
|
|
|
if opts is not None:
|
|
|
|
base_opts = opts.copy()
|
|
|
|
for key in base_opts:
|
|
|
|
if key in gramplet.__dict__:
|
|
|
|
base_opts[key] = gramplet.__dict__[key]
|
|
|
|
fp.write(("[%s]" + NL) % gramplet.title)
|
|
|
|
for key in base_opts:
|
2011-01-30 08:32:38 +05:30
|
|
|
if key in ["content", "title", "row", "column", "page",
|
|
|
|
"version", "gramps"]: # don't save
|
|
|
|
continue
|
2011-01-11 06:51:38 +05:30
|
|
|
elif key == "data":
|
|
|
|
if not isinstance(base_opts["data"], (list, tuple)):
|
|
|
|
fp.write(("data[0]=%s" + NL) % base_opts["data"])
|
|
|
|
else:
|
|
|
|
cnt = 0
|
|
|
|
for item in base_opts["data"]:
|
|
|
|
fp.write(("data[%d]=%s" + NL) % (cnt, item))
|
|
|
|
cnt += 1
|
|
|
|
else:
|
|
|
|
fp.write(("%s=%s" + NL)% (key, base_opts[key]))
|
|
|
|
fp.write(("page=%d" + NL) % page_num)
|
|
|
|
fp.write(NL)
|
|
|
|
|
|
|
|
fp.close()
|
|
|
|
|
|
|
|
def set_active(self):
|
|
|
|
"""
|
|
|
|
Called with the view is set as active.
|
|
|
|
"""
|
2011-02-02 23:02:13 +05:30
|
|
|
if not self.empty:
|
|
|
|
gramplet = self.get_nth_page(self.get_current_page())
|
|
|
|
if gramplet and gramplet.pui:
|
|
|
|
gramplet.pui.active = True
|
|
|
|
if gramplet.pui.dirty:
|
|
|
|
gramplet.pui.update()
|
2011-01-11 06:51:38 +05:30
|
|
|
|
|
|
|
def set_inactive(self):
|
|
|
|
"""
|
|
|
|
Called with the view is set as inactive.
|
|
|
|
"""
|
2011-02-02 23:02:13 +05:30
|
|
|
if not self.empty:
|
|
|
|
gramplet = self.get_nth_page(self.get_current_page())
|
|
|
|
if gramplet and gramplet.pui:
|
2011-01-30 08:32:38 +05:30
|
|
|
gramplet.pui.active = False
|
2011-01-11 06:51:38 +05:30
|
|
|
|
|
|
|
def on_delete(self):
|
|
|
|
"""
|
|
|
|
Called when the view is closed.
|
|
|
|
"""
|
2011-02-03 01:26:04 +05:30
|
|
|
map(self.__dock_gramplet, self.detached_gramplets)
|
2011-02-02 23:02:13 +05:30
|
|
|
if not self.empty:
|
|
|
|
for page_num in range(self.get_n_pages()):
|
|
|
|
gramplet = self.get_nth_page(page_num)
|
|
|
|
# this is the only place where the gui runs user code directly
|
|
|
|
if gramplet.pui:
|
|
|
|
gramplet.pui.on_save()
|
2011-01-30 08:32:38 +05:30
|
|
|
self.__save()
|
2011-01-11 06:51:38 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def add_gramplet(self, gname):
|
2011-01-11 06:51:38 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
Add a gramplet by name.
|
2011-01-11 06:51:38 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
if self.has_gramplet(gname):
|
|
|
|
return
|
|
|
|
all_opts = get_gramplet_options_by_name(gname)
|
|
|
|
gramplet = make_requested_gramplet(TabGramplet, self, all_opts,
|
|
|
|
self.dbstate, self.uistate)
|
|
|
|
if not gramplet:
|
|
|
|
print "Problem creating ", gname
|
|
|
|
return
|
2011-01-11 06:51:38 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
page_num = self.__add_tab(gramplet)
|
|
|
|
self.set_current_page(page_num)
|
2011-01-11 06:51:38 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def remove_gramplet(self, gname):
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
Remove a gramplet by name.
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-02-03 01:26:04 +05:30
|
|
|
for gramplet in self.detached_gramplets:
|
|
|
|
if gramplet.gname == gname:
|
|
|
|
self.__dock_gramplet(gramplet)
|
|
|
|
self.remove_page(self.page_num(gramplet))
|
|
|
|
return
|
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
for page_num in range(self.get_n_pages()):
|
|
|
|
gramplet = self.get_nth_page(page_num)
|
|
|
|
if gramplet.gname == gname:
|
|
|
|
self.remove_page(page_num)
|
|
|
|
return
|
2011-01-19 20:10:39 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def has_gramplet(self, gname):
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
Return True if the GrampsBar contains the gramplet, else False.
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-02-03 01:26:04 +05:30
|
|
|
return gname in self.all_gramplets()
|
2011-01-19 20:10:39 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def all_gramplets(self):
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
Return a list of names of all the gramplets in the GrampsBar.
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-02-02 23:02:13 +05:30
|
|
|
if self.empty:
|
|
|
|
return self.detached_gramplets
|
|
|
|
else:
|
|
|
|
return [gramplet.gname for gramplet in self.get_children() +
|
|
|
|
self.detached_gramplets]
|
|
|
|
|
|
|
|
def __create_empty_tab(self):
|
|
|
|
"""
|
|
|
|
Create an empty tab to be displayed when the GrampsBar is empty.
|
|
|
|
"""
|
|
|
|
tab_label = gtk.Label(_('Gramps Bar'))
|
|
|
|
tab_label.show()
|
|
|
|
msg = _('Right-click to the right of the tab to add a gramplet.')
|
|
|
|
content = gtk.Label(msg)
|
|
|
|
content.show()
|
|
|
|
self.append_page(content, tab_label)
|
|
|
|
return content
|
2011-01-19 20:10:39 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def __add_clicked(self):
|
2011-01-11 06:51:38 +05:30
|
|
|
"""
|
|
|
|
Called when the add button is clicked.
|
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
skip = self.all_gramplets()
|
|
|
|
names = [name for name in AVAILABLE_GRAMPLETS() if name not in skip]
|
|
|
|
gramplet_list = [(GET_AVAILABLE_GRAMPLETS(name)["tname"], name)
|
|
|
|
for name in names]
|
2011-01-11 06:51:38 +05:30
|
|
|
gramplet_list.sort()
|
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
dialog = ChooseGrampletDialog(_("Select Gramplet"), gramplet_list)
|
|
|
|
name = dialog.run()
|
|
|
|
if name:
|
|
|
|
self.add_gramplet(name)
|
2011-01-14 05:43:59 +05:30
|
|
|
|
|
|
|
def __add_tab(self, gramplet):
|
|
|
|
"""
|
|
|
|
Add a tab to the notebook for the given gramplet.
|
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
gramplet.set_size_request(gramplet.width, gramplet.height)
|
|
|
|
page_num = self.append_page(gramplet)
|
|
|
|
return page_num
|
|
|
|
|
|
|
|
def __create_tab_label(self, gramplet):
|
|
|
|
"""
|
|
|
|
Create a tab label consisting of a label and a close button.
|
|
|
|
"""
|
|
|
|
hbox = gtk.HBox(False, 4)
|
2011-01-14 05:43:59 +05:30
|
|
|
label = gtk.Label(gramplet.title)
|
|
|
|
label.set_tooltip_text(gramplet.tname)
|
2011-01-30 08:32:38 +05:30
|
|
|
closebtn = gtk.Button()
|
|
|
|
image = gtk.Image()
|
|
|
|
image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU)
|
|
|
|
closebtn.connect("clicked", self.__delete_clicked, gramplet)
|
|
|
|
closebtn.set_image(image)
|
|
|
|
closebtn.set_relief(gtk.RELIEF_NONE)
|
|
|
|
|
|
|
|
# The next three lines adjust the close button to the correct size.
|
|
|
|
closebtn.set_name('tab-button')
|
|
|
|
size = gtk.icon_size_lookup_for_settings(closebtn.get_settings(),
|
|
|
|
gtk.ICON_SIZE_MENU)
|
|
|
|
closebtn.set_size_request(size[0] + 2, size[1] + 2)
|
|
|
|
|
|
|
|
hbox.pack_start(label, True, True)
|
|
|
|
hbox.pack_end(closebtn, False, False)
|
|
|
|
hbox.show_all()
|
|
|
|
return hbox
|
2011-01-11 06:51:38 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def __delete_clicked(self, button, gramplet):
|
2011-01-11 06:51:38 +05:30
|
|
|
"""
|
|
|
|
Called when the delete button is clicked.
|
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
page_num = self.page_num(gramplet)
|
|
|
|
self.remove_page(page_num)
|
|
|
|
|
2011-01-11 06:51:38 +05:30
|
|
|
def __switch_page(self, notebook, unused, new_page):
|
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
Called when the user has switched to a new GrampsBar page.
|
2011-01-11 06:51:38 +05:30
|
|
|
"""
|
|
|
|
old_page = notebook.get_current_page()
|
|
|
|
if old_page >= 0:
|
2011-01-30 08:32:38 +05:30
|
|
|
gramplet = self.get_nth_page(old_page)
|
|
|
|
if gramplet and gramplet.pui:
|
2011-02-02 23:02:13 +05:30
|
|
|
gramplet.pui.active = False
|
2011-01-30 08:32:38 +05:30
|
|
|
|
|
|
|
gramplet = self.get_nth_page(new_page)
|
2011-02-02 23:02:13 +05:30
|
|
|
if not self.empty:
|
|
|
|
if gramplet and gramplet.pui:
|
|
|
|
gramplet.pui.active = True
|
|
|
|
if gramplet.pui.dirty:
|
|
|
|
gramplet.pui.update()
|
2011-01-30 08:32:38 +05:30
|
|
|
|
|
|
|
def __page_added(self, notebook, unused, new_page):
|
|
|
|
"""
|
|
|
|
Called when a new page is added to the GrampsBar.
|
|
|
|
"""
|
|
|
|
gramplet = self.get_nth_page(new_page)
|
2011-02-02 23:02:13 +05:30
|
|
|
if self.empty:
|
|
|
|
if isinstance(gramplet, TabGramplet):
|
|
|
|
self.remove_page(0)
|
|
|
|
self.empty = False
|
|
|
|
else:
|
|
|
|
return
|
2011-01-30 08:32:38 +05:30
|
|
|
label = self.__create_tab_label(gramplet)
|
|
|
|
self.set_tab_label(gramplet, label)
|
|
|
|
self.set_tab_reorderable(gramplet, True)
|
|
|
|
self.set_tab_detachable(gramplet, True)
|
|
|
|
if gramplet in self.detached_gramplets:
|
|
|
|
self.detached_gramplets.remove(gramplet)
|
|
|
|
self.reorder_child(gramplet, gramplet.page)
|
|
|
|
|
2011-02-02 23:02:13 +05:30
|
|
|
def __page_removed(self, notebook, unused, page_num):
|
|
|
|
"""
|
|
|
|
Called when a page is removed to the GrampsBar.
|
|
|
|
"""
|
|
|
|
if self.get_n_pages() == 0:
|
|
|
|
self.empty = True
|
|
|
|
self.__create_empty_tab()
|
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def __create_window(self, grampsbar, gramplet, x_pos, y_pos):
|
|
|
|
"""
|
|
|
|
Called when the user has switched to a new GrampsBar page.
|
|
|
|
"""
|
|
|
|
gramplet.page = self.page_num(gramplet)
|
|
|
|
self.detached_gramplets.append(gramplet)
|
|
|
|
win = DetachedWindow(grampsbar, gramplet, x_pos, y_pos)
|
2011-02-03 01:26:04 +05:30
|
|
|
gramplet.detached_window = win
|
2011-01-30 08:32:38 +05:30
|
|
|
return win.get_notebook()
|
|
|
|
|
2011-02-03 01:26:04 +05:30
|
|
|
def __dock_gramplet(self, gramplet):
|
|
|
|
"""
|
|
|
|
Dock a detached gramplet.
|
|
|
|
"""
|
|
|
|
gramplet.detached_window.close()
|
|
|
|
gramplet.detached_window = None
|
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def __button_press(self, widget, event):
|
|
|
|
"""
|
|
|
|
Called when a button is pressed in the tabs section of the GrampsBar.
|
|
|
|
"""
|
|
|
|
if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
|
|
|
|
# TODO: We will probably want a context menu here.
|
|
|
|
self.__add_clicked()
|
|
|
|
|
2011-02-03 23:44:32 +05:30
|
|
|
def get_config_funcs(self):
|
|
|
|
"""
|
|
|
|
Return a list of configuration functions.
|
|
|
|
"""
|
|
|
|
funcs = []
|
|
|
|
if self.empty:
|
|
|
|
gramplets = []
|
|
|
|
else:
|
|
|
|
gramplets = self.get_children()
|
|
|
|
for gramplet in gramplets + self.detached_gramplets:
|
|
|
|
gui_options = gramplet.make_gui_options()
|
|
|
|
if gui_options:
|
|
|
|
funcs.append(self.__build_panel(gramplet, gui_options))
|
|
|
|
return funcs
|
|
|
|
|
|
|
|
def __build_panel(self, title, gui_options):
|
|
|
|
"""
|
|
|
|
Return a configuration function that returns the title of a page in
|
|
|
|
the Configure View dialog and a gtk container defining the page.
|
|
|
|
"""
|
|
|
|
def gramplet_panel(configdialog):
|
|
|
|
return title, gui_options
|
|
|
|
return gramplet_panel
|
|
|
|
|
2011-01-19 20:10:39 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
2011-01-30 08:32:38 +05:30
|
|
|
# TabGramplet class
|
2011-01-19 20:10:39 +05:30
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2011-01-30 08:32:38 +05:30
|
|
|
class TabGramplet(gtk.ScrolledWindow, GuiGramplet):
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
Class that handles the plugin interfaces for the GrampletBar.
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
def __init__(self, pane, dbstate, uistate, title, **kwargs):
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
Internal constructor for GUI portion of a gramplet.
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
gtk.ScrolledWindow.__init__(self)
|
|
|
|
GuiGramplet.__init__(self, pane, dbstate, uistate, title, **kwargs)
|
2011-01-19 20:10:39 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
self.scrolledwindow = self
|
|
|
|
self.textview = gtk.TextView()
|
|
|
|
self.buffer = UndoableBuffer()
|
|
|
|
self.text_length = 0
|
|
|
|
self.textview.set_buffer(self.buffer)
|
|
|
|
self.textview.connect("key-press-event", self.on_key_press_event)
|
|
|
|
self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
|
|
|
self.add(self.textview)
|
|
|
|
self.show_all()
|
2011-02-03 03:27:27 +05:30
|
|
|
self.track = []
|
2011-01-19 20:10:39 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def get_container_widget(self):
|
|
|
|
"""
|
|
|
|
Return the top level container widget.
|
|
|
|
"""
|
|
|
|
return self
|
2011-01-19 20:10:39 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
2011-01-30 08:32:38 +05:30
|
|
|
# DetachedWindow class
|
2011-01-19 20:10:39 +05:30
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2011-01-30 08:32:38 +05:30
|
|
|
class DetachedWindow(ManagedWindow.ManagedWindow):
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
Class for showing a detached gramplet.
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
def __init__(self, grampsbar, gramplet, x_pos, y_pos):
|
|
|
|
"""
|
|
|
|
Construct the window.
|
|
|
|
"""
|
|
|
|
self.title = gramplet.title + " " + _("Gramplet")
|
|
|
|
self.grampsbar = grampsbar
|
|
|
|
self.gramplet = gramplet
|
|
|
|
|
|
|
|
ManagedWindow.ManagedWindow.__init__(self, gramplet.uistate, [],
|
|
|
|
self.title)
|
|
|
|
self.set_window(gtk.Dialog("", gramplet.uistate.window,
|
|
|
|
gtk.DIALOG_DESTROY_WITH_PARENT,
|
|
|
|
(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)),
|
|
|
|
None,
|
|
|
|
self.title)
|
|
|
|
self.window.move(x_pos, y_pos)
|
|
|
|
self.window.set_size_request(gramplet.detached_width,
|
|
|
|
gramplet.detached_height)
|
|
|
|
self.window.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
|
|
|
|
self.window.connect('response', self.handle_response)
|
|
|
|
|
|
|
|
self.notebook = gtk.Notebook()
|
|
|
|
self.notebook.set_show_tabs(False)
|
|
|
|
self.notebook.set_show_border(False)
|
|
|
|
self.notebook.show()
|
|
|
|
self.window.vbox.add(self.notebook)
|
|
|
|
self.show()
|
|
|
|
|
|
|
|
def handle_response(self, object, response):
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
Callback for taking care of button clicks.
|
2011-01-19 20:10:39 +05:30
|
|
|
"""
|
2011-01-30 08:32:38 +05:30
|
|
|
if response in [gtk.RESPONSE_CLOSE, gtk.STOCK_CLOSE]:
|
|
|
|
self.close()
|
|
|
|
elif response == gtk.RESPONSE_HELP:
|
|
|
|
# translated name:
|
|
|
|
if self.gramplet.help_url:
|
|
|
|
if self.gramplet.help_url.startswith("http://"):
|
|
|
|
GrampsDisplay.url(self.gramplet.help_url)
|
|
|
|
else:
|
|
|
|
GrampsDisplay.help(self.gramplet.help_url)
|
|
|
|
else:
|
|
|
|
GrampsDisplay.help(WIKI_HELP_PAGE,
|
|
|
|
self.gramplet.tname.replace(" ", "_"))
|
2011-01-19 20:10:39 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def get_notebook(self):
|
|
|
|
"""
|
|
|
|
Return the notebook.
|
|
|
|
"""
|
|
|
|
return self.notebook
|
2011-01-19 20:10:39 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def build_menu_names(self, obj):
|
|
|
|
"""
|
|
|
|
Part of the GRAMPS window interface.
|
|
|
|
"""
|
|
|
|
return (self.title, 'Gramplet')
|
2011-01-19 20:10:39 +05:30
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
def get_title(self):
|
|
|
|
"""
|
|
|
|
Returns the window title.
|
|
|
|
"""
|
|
|
|
return self.title
|
|
|
|
|
|
|
|
def close(self, *args):
|
|
|
|
"""
|
|
|
|
Dock the detached gramplet back in the GrampsBar from where it came.
|
|
|
|
"""
|
|
|
|
size = self.window.get_size()
|
|
|
|
self.gramplet.detached_width = size[0]
|
|
|
|
self.gramplet.detached_height = size[1]
|
2011-02-03 01:26:04 +05:30
|
|
|
self.gramplet.detached_window = None
|
2011-01-30 08:32:38 +05:30
|
|
|
self.gramplet.reparent(self.grampsbar)
|
|
|
|
ManagedWindow.ManagedWindow.close(self, *args)
|
2011-01-11 06:51:38 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Choose Gramplet Dialog
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class ChooseGrampletDialog(object):
|
|
|
|
"""
|
|
|
|
A dialog to choose a gramplet
|
|
|
|
"""
|
|
|
|
def __init__(self, title, names):
|
|
|
|
self.title = title
|
|
|
|
self.names = names
|
|
|
|
self.namelist = None
|
|
|
|
self.namemodel = None
|
|
|
|
self.top = self._create_dialog()
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
"""
|
|
|
|
Run the dialog and return the result.
|
|
|
|
"""
|
|
|
|
self._populate_model()
|
|
|
|
response = self.top.run()
|
|
|
|
result = None
|
|
|
|
if response == gtk.RESPONSE_OK:
|
|
|
|
store, iter_ = self.namemodel.get_selected()
|
|
|
|
if iter_:
|
2011-01-30 08:32:38 +05:30
|
|
|
result = store.get_value(iter_, 1)
|
2011-01-11 06:51:38 +05:30
|
|
|
self.top.destroy()
|
|
|
|
return result
|
|
|
|
|
|
|
|
def _populate_model(self):
|
|
|
|
"""
|
|
|
|
Populate the model.
|
|
|
|
"""
|
|
|
|
self.namemodel.clear()
|
|
|
|
for name in self.names:
|
2011-01-30 08:32:38 +05:30
|
|
|
self.namemodel.add(name)
|
2011-01-11 06:51:38 +05:30
|
|
|
|
|
|
|
def _create_dialog(self):
|
|
|
|
"""
|
|
|
|
Create a dialog box to organize tags.
|
|
|
|
"""
|
|
|
|
# pylint: disable-msg=E1101
|
|
|
|
title = _("%(title)s - Gramps") % {'title': self.title}
|
|
|
|
top = gtk.Dialog(title)
|
|
|
|
top.set_default_size(400, 350)
|
|
|
|
top.set_modal(True)
|
|
|
|
top.set_has_separator(False)
|
|
|
|
top.vbox.set_spacing(5)
|
|
|
|
label = gtk.Label('<span size="larger" weight="bold">%s</span>'
|
|
|
|
% self.title)
|
|
|
|
label.set_use_markup(True)
|
|
|
|
top.vbox.pack_start(label, 0, 0, 5)
|
|
|
|
box = gtk.HBox()
|
|
|
|
top.vbox.pack_start(box, 1, 1, 5)
|
|
|
|
|
2011-01-30 08:32:38 +05:30
|
|
|
name_titles = [(_('Name'), NOSORT, 200),
|
|
|
|
('', NOSORT, 200)]
|
2011-01-11 06:51:38 +05:30
|
|
|
self.namelist = gtk.TreeView()
|
|
|
|
self.namemodel = ListModel(self.namelist, name_titles)
|
|
|
|
|
|
|
|
slist = gtk.ScrolledWindow()
|
|
|
|
slist.add_with_viewport(self.namelist)
|
|
|
|
slist.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
|
|
|
box.pack_start(slist, 1, 1, 5)
|
|
|
|
bbox = gtk.VButtonBox()
|
|
|
|
bbox.set_layout(gtk.BUTTONBOX_START)
|
|
|
|
bbox.set_spacing(6)
|
|
|
|
top.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
|
|
|
|
top.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
|
|
|
|
box.pack_start(bbox, 0, 0, 5)
|
|
|
|
top.show_all()
|
|
|
|
return top
|