gramps/src/gui/workspace.py
2010-12-15 19:40:27 +00:00

341 lines
11 KiB
Python

#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2010 Nick Hall
# Copyright (C) 2010 Douglas S. Blank <doug.blank@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$
"""
Workspace
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from gen.ggettext import gettext as _
#-------------------------------------------------------------------------
#
# GNOME modules
#
#-------------------------------------------------------------------------
import gtk
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
import Errors
from gui.sidebar import Sidebar
from gui.widgets.grampletpane import GrampletPane
from gui.views.listview import ListView
from gui.configure import ConfigureDialog
import config
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
GRAMPLET_PAGE = 0
FILTER_PAGE = 1
#-------------------------------------------------------------------------
#
# Workspace class
#
#-------------------------------------------------------------------------
class Workspace(object):
"""
A Workspace contains panes to contain a view and associated objects such as
a filter and gramplet pane.
"""
def __init__(self, uistate, dbstate):
self.uistate = uistate
self.dbstate = dbstate
self.active = False
self.view = None
self._config = None
self.sidebar = Sidebar(self.sidebar_changed, self.sidebar_closed)
self.hpane = gtk.HPaned()
self.vpane = gtk.VPaned()
self.hpane.pack1(self.vpane, resize=True, shrink=True)
self.hpane.pack2(self.sidebar.get_display(), resize=False, shrink=False)
self.hpane.show()
self.vpane.show()
def get_display(self):
"""
Return the top container widget for the GUI.
"""
return self.hpane
def add_view(self, view):
"""
Add a view to the workspace.
"""
self.view = view
self.vpane.add1(view.get_display())
initial_page = self.view._config.get('sidebar.page')
self.gramplet_pane = self.__create_gramplet_pane()
if isinstance(view, ListView):
self.add_filter(view.filter_class)
if self.view._config.get('sidebar.visible'):
self.sidebar.show()
else:
self.sidebar.hide()
self.sidebar.set_current_page(initial_page)
def add_aux(self, aux):
"""
Add an auxilliary object to the workspace.
"""
self.aux = aux
self.vpane.add2(aux.get_display())
def add_filter(self, filter_class):
"""
Add a filter to the workspace sidebar.
"""
self.filter_sidebar = filter_class(self.dbstate, self.uistate,
self.__filter_clicked)
top = self.filter_sidebar.get_widget()
top.show_all()
self.sidebar.add(_('Filter'), top, FILTER_PAGE)
def remove_filter(self,):
"""
Remove the filter from the workspace sidebar.
"""
self.filter_sidebar = None
self.sidebar.remove(FILTER_PAGE)
def __create_gramplet_pane(self):
"""
Create a gramplet pane.
"""
self.uidef = '''<ui>
<menubar name="MenuBar">
<menu action="ViewMenu">
<placeholder name="Bars">
<menuitem action="Sidebar"/>
</placeholder>
</menu>
</menubar>
<popup name="Popup">
<menuitem action="AddGramplet"/>
<menuitem action="RestoreGramplet"/>
</popup>
</ui>'''
eb = gtk.EventBox()
eb.connect('button-press-event', self._gramplet_button_press)
gramplet_pane = GrampletPane(self.view.ident + "_sidebar",
self, self.dbstate, self.uistate,
column_count=1)
gramplet_pane.show_all()
eb.add(gramplet_pane)
eb.show()
self.sidebar.add(_('Gramplets'), eb, GRAMPLET_PAGE)
return gramplet_pane
def _gramplet_button_press(self, obj, event):
"""
Called to display the context menu in the gramplet pane.
"""
if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
menu = self.uistate.uimanager.get_widget('/Popup')
if menu:
menu.popup(None, None, None, event.button, event.time)
return True
def __filter_clicked(self):
"""
Called when the filter 'Find' button is clicked.
"""
self.view.generic_filter = self.filter_sidebar.get_filter()
self.view.build_tree()
def __sidebar_toggled(self, action):
"""
Called when the sidebar is toggled.
"""
active = action.get_active()
if active:
self.sidebar.show()
self.sidebar_changed(self.sidebar.get_page_type(), True, None)
else:
self.sidebar.hide()
self.sidebar_changed(None, False, None)
self.view._config.set('sidebar.visible', active)
def sidebar_changed(self, page_type, active, index):
"""
Called when the sidebar page is changed.
"""
if index is not None:
self.view._config.set('sidebar.page', index)
if isinstance(self.view, ListView):
if active and page_type == FILTER_PAGE:
self.view.search_bar.hide()
else:
self.view.search_bar.show()
def sidebar_closed(self):
"""
Called when the sidebar close button is clicked.
"""
uimanager = self.uistate.uimanager
uimanager.get_action('/MenuBar/ViewMenu/Bars/Sidebar').activate()
def get_title(self):
"""
Return the title of the view.
"""
if self.view:
return self.view.title
return ''
def define_actions(self):
"""
Defines the UIManager actions.
"""
self.action_group = gtk.ActionGroup('Workspace')
self.action_group.add_toggle_actions([
('Sidebar', None, _('_Sidebar'),
None, None, self.__sidebar_toggled,
self.view._config.get('sidebar.visible'))
])
self.action_group.add_actions([
("AddGramplet", None, _("Add a gramplet")),
("RestoreGramplet", None, _("Restore a gramplet")
)])
def set_active(self):
"""
Called when the view is set as active.
"""
self.active = True
self.gramplet_pane.set_active()
self.view.set_active()
def set_inactive(self):
"""
Called when the view is set as inactive.
"""
self.active = False
self.gramplet_pane.set_inactive()
self.view.set_inactive()
def get_actions(self):
"""
Return the actions that should be used for the view.
"""
action_list = self.view.get_actions()
action_list.append(self.action_group)
return action_list
def ui_definition(self):
"""
Returns the XML UI definition for the UIManager.
"""
return self.view.ui_definition()
def additional_ui_definitions(self):
"""
Return any additional interfaces for the UIManager that the view
needs to define.
"""
defs = self.view.additional_ui_definitions()
defs.append(self.uidef)
return defs
def change_page(self):
"""
Called when the view changes.
"""
self.view.change_page()
def on_delete(self):
"""
Method called on shutdown.
"""
self.view.on_delete()
self.gramplet_pane.on_delete()
def can_configure(self):
"""
Returns True if the workspace has a configure window.
"""
return self.view.can_configure() or self.gramplet_pane.can_configure()
def _get_configure_page_funcs(self):
"""
Return a list of functions that create gtk elements to use in the
notebook pages of the Configuration dialog.
"""
retval = []
if self.view.can_configure():
other = self.view._get_configure_page_funcs()
if callable(other):
retval += other()
else:
retval += other
func = self.gramplet_pane._get_configure_page_funcs()
return retval + func()
def configure(self):
"""
Open the configure dialog for the workspace.
"""
__configure_content = self._get_configure_page_funcs()
title = _("Configure %(cat)s - %(view)s") % \
{'cat': self.view.get_translated_category(),
'view': self.view.get_title()}
try:
ViewConfigureDialog(self.uistate, self.dbstate,
__configure_content,
self, self.view._config, dialogtitle=title,
ident=_("%(cat)s - %(view)s") %
{'cat': self.view.get_translated_category(),
'view': self.view.get_title()})
except Errors.WindowActiveError:
return
class ViewConfigureDialog(ConfigureDialog):
"""
All workspaces can have their own configuration dialog
"""
def __init__(self, uistate, dbstate, configure_page_funcs, configobj,
configmanager,
dialogtitle=_("Preferences"), on_close=None, ident=''):
self.ident = ident
ConfigureDialog.__init__(self, uistate, dbstate, configure_page_funcs,
configobj, configmanager,
dialogtitle=dialogtitle, on_close=on_close)
def build_menu_names(self, obj):
return (_('Configure %s View') % self.ident, None)