Introduce workspaces with a shared filter/gramplet sidebar
svn: r16160
This commit is contained in:
171
src/gui/navigator.py
Normal file
171
src/gui/navigator.py
Normal file
@@ -0,0 +1,171 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2010 Nick Hall
|
||||
#
|
||||
# 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$
|
||||
|
||||
"""
|
||||
A module that provides pluggable sidebars. These provide an interface to
|
||||
manage pages in the main Gramps window.
|
||||
"""
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GNOME modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.plug import (START, END)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Navigator class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class Navigator(object):
|
||||
"""
|
||||
A class which defines the graphical representation of the Gramps navigator.
|
||||
"""
|
||||
def __init__(self, viewmanager):
|
||||
|
||||
self.viewmanager = viewmanager
|
||||
self.pages = []
|
||||
self.top = gtk.VBox()
|
||||
|
||||
frame = gtk.Frame()
|
||||
hbox = gtk.HBox()
|
||||
frame.add(hbox)
|
||||
|
||||
select_button = gtk.ToggleButton()
|
||||
select_button.set_relief(gtk.RELIEF_NONE)
|
||||
select_hbox = gtk.HBox()
|
||||
#self.title_label = gtk.Label('')
|
||||
arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_NONE)
|
||||
#select_hbox.pack_start(self.title_label, False)
|
||||
select_hbox.pack_end(arrow, False)
|
||||
select_button.add(select_hbox)
|
||||
|
||||
select_button.connect('button_press_event', self.__menu_button_pressed)
|
||||
|
||||
#close_button = gtk.Button()
|
||||
#img = gtk.image_new_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU)
|
||||
#close_button.set_image(img)
|
||||
#close_button.set_relief(gtk.RELIEF_NONE)
|
||||
#close_button.connect('clicked', self.cb_close_clicked)
|
||||
hbox.pack_start(select_button, False)
|
||||
#hbox.pack_end(close_button, False)
|
||||
|
||||
self.top.pack_end(frame, False)
|
||||
|
||||
self.menu = gtk.Menu()
|
||||
self.menu.show()
|
||||
self.menu.connect('deactivate', cb_menu_deactivate, select_button)
|
||||
|
||||
self.notebook = gtk.Notebook()
|
||||
self.notebook.show()
|
||||
self.notebook.set_show_tabs(False)
|
||||
self.notebook.set_show_border(False)
|
||||
self.notebook.connect('switch_page', self.cb_switch_page)
|
||||
self.top.pack_start(self.notebook, True)
|
||||
|
||||
def get_top(self):
|
||||
"""
|
||||
Return the top container widget for the GUI.
|
||||
"""
|
||||
return self.top
|
||||
|
||||
def add(self, title, sidebar, order):
|
||||
"""
|
||||
Add a page to the sidebar for a plugin.
|
||||
"""
|
||||
self.pages.append((title, sidebar))
|
||||
index = self.notebook.append_page(sidebar.get_top(), gtk.Label(title))
|
||||
|
||||
menu_item = gtk.MenuItem(title)
|
||||
if order == START:
|
||||
self.menu.prepend(menu_item)
|
||||
self.notebook.set_current_page(index)
|
||||
else:
|
||||
self.menu.append(menu_item)
|
||||
menu_item.connect('activate', self.cb_menu_activate, index)
|
||||
menu_item.show()
|
||||
|
||||
def view_changed(self, cat_num, view_num):
|
||||
"""
|
||||
Called when a Gramps view is changed.
|
||||
"""
|
||||
for page in self.pages:
|
||||
page[1].view_changed(cat_num, view_num)
|
||||
|
||||
def __menu_button_pressed(self, button, event):
|
||||
"""
|
||||
Called when the button to select a sidebar page is pressed.
|
||||
"""
|
||||
if event.button == 1 and event.type == gtk.gdk.BUTTON_PRESS:
|
||||
button.grab_focus()
|
||||
button.set_active(True)
|
||||
|
||||
self.menu.popup(None, None, cb_menu_position, event.button,
|
||||
event.time, button)
|
||||
|
||||
def cb_menu_activate(self, menu, index):
|
||||
"""
|
||||
Called when an item in the popup menu is selected.
|
||||
"""
|
||||
self.notebook.set_current_page(index)
|
||||
|
||||
def cb_switch_page(self, notebook, unused, index):
|
||||
"""
|
||||
Called when the user has switched to a new sidebar plugin page.
|
||||
"""
|
||||
pass
|
||||
#if self.pages:
|
||||
#self.title_label.set_text(self.pages[index][0])
|
||||
|
||||
def cb_close_clicked(self, button):
|
||||
"""
|
||||
Called when the sidebar is closed.
|
||||
"""
|
||||
uimanager = self.viewmanager.uimanager
|
||||
uimanager.get_action('/MenuBar/ViewMenu/Navigator').activate()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def cb_menu_position(menu, button):
|
||||
"""
|
||||
Determine the position of the popup menu.
|
||||
"""
|
||||
x_pos, y_pos = button.window.get_origin()
|
||||
x_pos += button.allocation.x
|
||||
y_pos += button.allocation.y + button.allocation.height
|
||||
|
||||
return (x_pos, y_pos, False)
|
||||
|
||||
def cb_menu_deactivate(menu, button):
|
||||
"""
|
||||
Called when the popup menu disappears.
|
||||
"""
|
||||
button.set_active(False)
|
@@ -19,10 +19,13 @@
|
||||
#
|
||||
# $Id$
|
||||
|
||||
"""
|
||||
A module that provides pluggable sidebars. These provide an interface to
|
||||
manage pages in the main Gramps window.
|
||||
"""
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.ggettext import gettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GNOME modules
|
||||
@@ -35,7 +38,7 @@ import gtk
|
||||
# Gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gen.plug import (START, END)
|
||||
import config
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -46,9 +49,9 @@ class Sidebar(object):
|
||||
"""
|
||||
A class which defines the graphical representation of the Gramps sidebar.
|
||||
"""
|
||||
def __init__(self, viewmanager):
|
||||
def __init__(self, callback):
|
||||
|
||||
self.viewmanager = viewmanager
|
||||
self.callback = callback
|
||||
self.pages = []
|
||||
self.top = gtk.VBox()
|
||||
|
||||
@@ -59,7 +62,7 @@ class Sidebar(object):
|
||||
select_button = gtk.ToggleButton()
|
||||
select_button.set_relief(gtk.RELIEF_NONE)
|
||||
select_hbox = gtk.HBox()
|
||||
self.title_label = gtk.Label('')
|
||||
self.title_label = gtk.Label()
|
||||
arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_NONE)
|
||||
select_hbox.pack_start(self.title_label, False)
|
||||
select_hbox.pack_end(arrow, False)
|
||||
@@ -71,51 +74,66 @@ class Sidebar(object):
|
||||
img = gtk.image_new_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU)
|
||||
close_button.set_image(img)
|
||||
close_button.set_relief(gtk.RELIEF_NONE)
|
||||
close_button.connect('clicked', self.cb_close_clicked)
|
||||
close_button.connect('clicked', self.__close_clicked)
|
||||
hbox.pack_start(select_button, False)
|
||||
hbox.pack_end(close_button, False)
|
||||
|
||||
|
||||
self.top.pack_start(frame, False)
|
||||
|
||||
self.menu = gtk.Menu()
|
||||
self.menu.show()
|
||||
self.menu.connect('deactivate', cb_menu_deactivate, select_button)
|
||||
self.menu.connect('deactivate', self.__menu_deactivate, select_button)
|
||||
|
||||
self.notebook = gtk.Notebook()
|
||||
self.notebook.show()
|
||||
self.notebook.set_show_tabs(False)
|
||||
self.notebook.set_show_border(False)
|
||||
self.notebook.connect('switch_page', self.cb_switch_page)
|
||||
self.notebook.connect('switch_page', self.__switch_page)
|
||||
self.top.pack_start(self.notebook, True)
|
||||
self.top.show_all()
|
||||
|
||||
def get_top(self):
|
||||
def get_display(self):
|
||||
"""
|
||||
Return the top container widget for the GUI.
|
||||
"""
|
||||
return self.top
|
||||
|
||||
def get_page_type(self):
|
||||
"""
|
||||
Return the type of the active page.
|
||||
"""
|
||||
return self.pages[self.notebook.get_current_page()][1]
|
||||
|
||||
def add(self, title, sidebar, order):
|
||||
def add(self, title, container, page_type):
|
||||
"""
|
||||
Add a page to the sidebar for a plugin.
|
||||
Add a page to the sidebar.
|
||||
"""
|
||||
self.pages.append((title, sidebar))
|
||||
index = self.notebook.append_page(sidebar.get_top(), gtk.Label(title))
|
||||
|
||||
menu_item = gtk.MenuItem(title)
|
||||
if order == START:
|
||||
self.menu.prepend(menu_item)
|
||||
self.notebook.set_current_page(index)
|
||||
else:
|
||||
self.menu.append(menu_item)
|
||||
menu_item.connect('activate', self.cb_menu_activate, index)
|
||||
self.pages.append([title, page_type, menu_item])
|
||||
index = self.notebook.append_page(container, gtk.Label(title))
|
||||
menu_item.connect('activate', self.__menu_activate, index)
|
||||
menu_item.show()
|
||||
self.menu.append(menu_item)
|
||||
self.notebook.set_current_page(index)
|
||||
|
||||
def view_changed(self, cat_num, view_num):
|
||||
def remove(self, page_type):
|
||||
"""
|
||||
Called when a Gramps view is changed.
|
||||
Replace a page in the sidebar.
|
||||
"""
|
||||
for page in self.pages:
|
||||
page[1].view_changed(cat_num, view_num)
|
||||
position = self.__get_page(page_type)
|
||||
if position is not None:
|
||||
self.notebook.remove_page(position)
|
||||
self.menu.remove(self.pages[position][2])
|
||||
self.pages = self.pages[:position] + self.pages[position+1:]
|
||||
|
||||
def __get_page(self, page_type):
|
||||
"""
|
||||
Return the page number of the page with the given type.
|
||||
"""
|
||||
for page_num, page in enumerate(self.pages):
|
||||
if page[1] == page_type:
|
||||
return page_num
|
||||
return None
|
||||
|
||||
def __menu_button_pressed(self, button, event):
|
||||
"""
|
||||
@@ -125,46 +143,43 @@ class Sidebar(object):
|
||||
button.grab_focus()
|
||||
button.set_active(True)
|
||||
|
||||
self.menu.popup(None, None, cb_menu_position, event.button,
|
||||
self.menu.popup(None, None, self.__menu_position, event.button,
|
||||
event.time, button)
|
||||
|
||||
def cb_menu_activate(self, menu, index):
|
||||
|
||||
def __menu_position(self, menu, button):
|
||||
"""
|
||||
Determine the position of the popup menu.
|
||||
"""
|
||||
x, y = button.window.get_origin()
|
||||
x += button.allocation.x
|
||||
y += button.allocation.y + button.allocation.height
|
||||
|
||||
return (x, y, False)
|
||||
|
||||
def __menu_activate(self, menu, index):
|
||||
"""
|
||||
Called when an item in the popup menu is selected.
|
||||
"""
|
||||
"""
|
||||
self.notebook.set_current_page(index)
|
||||
|
||||
def cb_switch_page(self, notebook, unused, index):
|
||||
def __menu_deactivate(self, menu, button):
|
||||
"""
|
||||
Called when the user has switched to a new sidebar plugin page.
|
||||
Called when the popup menu disappears.
|
||||
"""
|
||||
button.set_active(False)
|
||||
|
||||
def __switch_page(self, notebook, unused, index):
|
||||
"""
|
||||
Called when the user has switched to a new sidebar page.
|
||||
"""
|
||||
if self.pages:
|
||||
self.title_label.set_text(self.pages[index][0])
|
||||
self.title_label.set_markup('<b>%s</b>' % self.pages[index][0])
|
||||
active = self.top.get_property('visible')
|
||||
self.callback(self.pages[index][1], active)
|
||||
|
||||
def cb_close_clicked(self, button):
|
||||
def __close_clicked(self, button):
|
||||
"""
|
||||
Called when the sidebar is closed.
|
||||
"""
|
||||
uimanager = self.viewmanager.uimanager
|
||||
uimanager.get_action('/MenuBar/ViewMenu/Sidebar').activate()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def cb_menu_position(menu, button):
|
||||
"""
|
||||
Determine the position of the popup menu.
|
||||
"""
|
||||
x_pos, y_pos = button.window.get_origin()
|
||||
x_pos += button.allocation.x
|
||||
y_pos += button.allocation.y + button.allocation.height
|
||||
|
||||
return (x_pos, y_pos, False)
|
||||
|
||||
def cb_menu_deactivate(menu, button):
|
||||
"""
|
||||
Called when the popup menu disappears.
|
||||
"""
|
||||
button.set_active(False)
|
||||
config.set('interface.filter', False)
|
||||
config.save()
|
||||
|
@@ -89,7 +89,8 @@ from gui.configure import GrampsPreferences
|
||||
from gen.db.backup import backup
|
||||
from gen.db.exceptions import DbException
|
||||
from GrampsAboutDialog import GrampsAboutDialog
|
||||
from gui.sidebar import Sidebar
|
||||
from workspace import Workspace
|
||||
from gui.navigator import Navigator
|
||||
from gui.views.tags import Tags
|
||||
from gen.utils.configmanager import safe_eval
|
||||
|
||||
@@ -130,9 +131,9 @@ UIDEFAULT = '''<ui>
|
||||
</menu>
|
||||
<menu action="ViewMenu">
|
||||
<menuitem action="ConfigView"/>
|
||||
<menuitem action="Sidebar"/>
|
||||
<menuitem action="Navigator"/>
|
||||
<menuitem action="Toolbar"/>
|
||||
<menuitem action="Filter"/>
|
||||
<menuitem action="Sidebar"/>
|
||||
<menuitem action="Fullscreen"/>
|
||||
<separator/>
|
||||
<placeholder name="ViewsInCategory"/>
|
||||
@@ -278,9 +279,9 @@ class ViewManager(CLIManager):
|
||||
self.views = None
|
||||
self.current_views = [] # The current view in each category
|
||||
|
||||
self.show_sidebar = config.get('interface.view')
|
||||
self.show_navigator = config.get('interface.view')
|
||||
self.show_toolbar = config.get('interface.toolbar-on')
|
||||
self.show_filter = config.get('interface.filter')
|
||||
self.show_sidebar = config.get('interface.filter')
|
||||
self.fullscreen = config.get('interface.fullscreen')
|
||||
|
||||
self.__build_main_window()
|
||||
@@ -515,8 +516,8 @@ class ViewManager(CLIManager):
|
||||
hpane = gtk.HPaned()
|
||||
self.ebox = gtk.EventBox()
|
||||
|
||||
self.sidebar = Sidebar(self)
|
||||
self.ebox.add(self.sidebar.get_top())
|
||||
self.navigator = Navigator(self)
|
||||
self.ebox.add(self.navigator.get_top())
|
||||
hpane.add1(self.ebox)
|
||||
hpane.show_all()
|
||||
|
||||
@@ -547,8 +548,8 @@ class ViewManager(CLIManager):
|
||||
|
||||
self.tags = Tags(self.uistate, self.dbstate)
|
||||
|
||||
self.filter_menu = self.uimanager.get_widget(
|
||||
'/MenuBar/ViewMenu/Filter/')
|
||||
self.sidebar_menu = self.uimanager.get_widget(
|
||||
'/MenuBar/ViewMenu/Sidebar/')
|
||||
|
||||
# handle OPEN button, insert it into the toolbar. Unfortunately,
|
||||
# UIManager has no built in support for and Open Recent button
|
||||
@@ -563,7 +564,7 @@ class ViewManager(CLIManager):
|
||||
|
||||
self.db_loader = DbLoader(self.dbstate, self.uistate)
|
||||
|
||||
self.__setup_sidebar()
|
||||
self.__setup_navigator()
|
||||
|
||||
if self.show_toolbar:
|
||||
self.toolbar.show()
|
||||
@@ -591,7 +592,7 @@ class ViewManager(CLIManager):
|
||||
|
||||
sidebar_class = getattr(module, pdata.sidebarclass)
|
||||
sidebar_page = sidebar_class(self.dbstate, self.uistate)
|
||||
self.sidebar.add(pdata.menu_label, sidebar_page, pdata.order)
|
||||
self.navigator.add(pdata.menu_label, sidebar_page, pdata.order)
|
||||
|
||||
def __setup_statusbar(self):
|
||||
"""
|
||||
@@ -615,12 +616,12 @@ class ViewManager(CLIManager):
|
||||
hbox2.show()
|
||||
return hbox2
|
||||
|
||||
def __setup_sidebar(self):
|
||||
def __setup_navigator(self):
|
||||
"""
|
||||
If we have enabled te sidebar, show it, and turn off the tabs. If
|
||||
disabled, hide the sidebar and turn on the tabs.
|
||||
"""
|
||||
if self.show_sidebar:
|
||||
if self.show_navigator:
|
||||
self.ebox.show()
|
||||
else:
|
||||
self.ebox.hide()
|
||||
@@ -733,12 +734,12 @@ class ViewManager(CLIManager):
|
||||
]
|
||||
|
||||
self._file_toggle_action_list = [
|
||||
('Sidebar', None, _('_Sidebar'), None, None, self.sidebar_toggle,
|
||||
self.show_sidebar ),
|
||||
('Navigator', None, _('_Navigator'), None, None,
|
||||
self.navigator_toggle, self.show_navigator ),
|
||||
('Toolbar', None, _('_Toolbar'), None, None, self.toolbar_toggle,
|
||||
self.show_toolbar ),
|
||||
('Filter', None, _('_Filter Sidebar'), None, None,
|
||||
filter_toggle, self.show_filter),
|
||||
('Sidebar', None, _('_Sidebar'), None, None,
|
||||
sidebar_toggle, self.show_sidebar),
|
||||
('Fullscreen', None, _('F_ull Screen'), "F11", None,
|
||||
self.fullscreen_toggle, self.fullscreen),
|
||||
]
|
||||
@@ -814,10 +815,8 @@ class ViewManager(CLIManager):
|
||||
self.__rebuild_report_and_tool_menus)
|
||||
self.fileactions.set_sensitive(True)
|
||||
self.uistate.widget.set_sensitive(True)
|
||||
config.connect("interface.statusbar",
|
||||
self.__statusbar_key_update)
|
||||
config.connect("interface.filter",
|
||||
self.__filter_signal)
|
||||
config.connect("interface.statusbar", self.__statusbar_key_update)
|
||||
config.connect("interface.filter", self.__sidebar_signal)
|
||||
|
||||
def __statusbar_key_update(self, client, cnxn_id, entry, data):
|
||||
"""
|
||||
@@ -825,12 +824,12 @@ class ViewManager(CLIManager):
|
||||
"""
|
||||
self.uistate.modify_statusbar(self.dbstate)
|
||||
|
||||
def __filter_signal(self, client, cnxn_id, entry, data):
|
||||
def __sidebar_signal(self, client, cnxn_id, entry, data):
|
||||
"""
|
||||
Callback function for statusbar key update
|
||||
Callback function for sidebar key update
|
||||
"""
|
||||
if self.filter_menu.get_active() != config.get('interface.filter'):
|
||||
self.filter_menu.set_active(config.get('interface.filter'))
|
||||
if self.sidebar_menu.get_active() != config.get('interface.filter'):
|
||||
self.sidebar_menu.set_active(config.get('interface.filter'))
|
||||
|
||||
def post_init_interface(self, show_manager=True):
|
||||
"""
|
||||
@@ -995,7 +994,7 @@ class ViewManager(CLIManager):
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def sidebar_toggle(self, obj):
|
||||
def navigator_toggle(self, obj):
|
||||
"""
|
||||
Set the sidebar based on the value of the toggle button. Save the
|
||||
results in the configuration settings
|
||||
@@ -1003,11 +1002,11 @@ class ViewManager(CLIManager):
|
||||
if obj.get_active():
|
||||
self.ebox.show()
|
||||
config.set('interface.view', True)
|
||||
self.show_sidebar = True
|
||||
self.show_navigator = True
|
||||
else:
|
||||
self.ebox.hide()
|
||||
config.set('interface.view', False)
|
||||
self.show_sidebar = False
|
||||
self.show_navigator = False
|
||||
config.save()
|
||||
|
||||
def toolbar_toggle(self, obj):
|
||||
@@ -1084,8 +1083,9 @@ class ViewManager(CLIManager):
|
||||
"""
|
||||
Create a new page and set it as the current page.
|
||||
"""
|
||||
wspace = Workspace(self.uistate, self.dbstate)
|
||||
try:
|
||||
page = page_def(self.dbstate, self.uistate)
|
||||
page = page_def(self.dbstate, self.uistate, wspace)
|
||||
except:
|
||||
import traceback
|
||||
LOG.warn("View '%s' failed to load." % pdata.id)
|
||||
@@ -1109,7 +1109,9 @@ class ViewManager(CLIManager):
|
||||
return
|
||||
page_display.show_all()
|
||||
page.post()
|
||||
self.pages.append(page)
|
||||
|
||||
wspace.add_view(page)
|
||||
self.pages.append(wspace)
|
||||
|
||||
# create icon/label for workspace notebook
|
||||
hbox = gtk.HBox()
|
||||
@@ -1118,8 +1120,7 @@ class ViewManager(CLIManager):
|
||||
hbox.pack_start(image, False)
|
||||
hbox.add(gtk.Label(pdata.name))
|
||||
hbox.show_all()
|
||||
page_num = self.notebook.append_page(page_display,
|
||||
hbox)
|
||||
page_num = self.notebook.append_page(wspace.get_display(), hbox)
|
||||
|
||||
def view_changed(self, notebook, page, page_num):
|
||||
"""
|
||||
@@ -1142,7 +1143,7 @@ class ViewManager(CLIManager):
|
||||
config.set('preferences.last-views', last_views)
|
||||
config.save()
|
||||
|
||||
self.sidebar.view_changed(cat_num, view_num)
|
||||
self.navigator.view_changed(cat_num, view_num)
|
||||
self.__change_page(page_num)
|
||||
|
||||
def __change_page(self, page_num):
|
||||
@@ -1663,7 +1664,7 @@ def display_about_box(obj):
|
||||
about.run()
|
||||
about.destroy()
|
||||
|
||||
def filter_toggle(obj):
|
||||
def sidebar_toggle(obj):
|
||||
"""
|
||||
Save the filter state to the config settings on change
|
||||
"""
|
||||
|
@@ -175,11 +175,7 @@ class ListView(NavigationView):
|
||||
self.selection.connect('changed', self.row_changed)
|
||||
|
||||
self.setup_filter()
|
||||
|
||||
if self.filter_class:
|
||||
return self.build_filter_container(self.vbox, self.filter_class)
|
||||
else:
|
||||
return self.vbox
|
||||
return self.vbox
|
||||
|
||||
def define_actions(self):
|
||||
"""
|
||||
@@ -252,7 +248,7 @@ class ListView(NavigationView):
|
||||
def build_tree(self, force_sidebar=False):
|
||||
if self.active:
|
||||
cput0 = time.clock()
|
||||
if config.get('interface.filter') or force_sidebar:
|
||||
if not self.search_bar.is_visible():
|
||||
filter_info = (True, self.generic_filter, False)
|
||||
else:
|
||||
value = self.search_bar.get_value()
|
||||
@@ -308,50 +304,11 @@ class ListView(NavigationView):
|
||||
"""
|
||||
return ()
|
||||
|
||||
####################################################################
|
||||
# Filter
|
||||
####################################################################
|
||||
def build_filter_container(self, box, filter_class):
|
||||
self.filter_sidebar = filter_class(self.dbstate, self.uistate,
|
||||
self.filter_clicked)
|
||||
self.filter_pane = self.filter_sidebar.get_widget()
|
||||
|
||||
hpaned = gtk.HBox()
|
||||
hpaned.pack_start(self.vbox, True, True)
|
||||
hpaned.pack_end(self.filter_pane, False, False)
|
||||
self.filter_toggle(None, None, None, None)
|
||||
return hpaned
|
||||
|
||||
def filter_toggle(self, client, cnxn_id, entry, data):
|
||||
"""
|
||||
Callback on change interface.filter, inheriting methods connect to
|
||||
change in ini file
|
||||
"""
|
||||
if config.get('interface.filter'):
|
||||
self.search_bar.hide()
|
||||
self.filter_pane.show()
|
||||
else:
|
||||
self.search_bar.show()
|
||||
self.filter_pane.hide()
|
||||
|
||||
def post(self):
|
||||
if self.filter_class:
|
||||
if config.get('interface.filter'):
|
||||
self.search_bar.hide()
|
||||
self.filter_pane.show()
|
||||
else:
|
||||
self.search_bar.show()
|
||||
self.filter_pane.hide()
|
||||
|
||||
def get_viewtype_stock(self):
|
||||
"""Type of view in category, default listview is a flat list
|
||||
"""
|
||||
return 'gramps-tree-list'
|
||||
|
||||
def filter_clicked(self):
|
||||
self.generic_filter = self.filter_sidebar.get_filter()
|
||||
self.build_tree()
|
||||
|
||||
def filter_editor(self, obj):
|
||||
try:
|
||||
FilterEditor(self.FILTER_TYPE , const.CUSTOM_FILTERS,
|
||||
@@ -588,7 +545,7 @@ class ListView(NavigationView):
|
||||
self.sort_order = order
|
||||
handle = self.first_selected()
|
||||
|
||||
if config.get('interface.filter'):
|
||||
if not self.search_bar.is_visible():
|
||||
filter_info = (True, self.generic_filter, False)
|
||||
else:
|
||||
value = self.search_bar.get_value()
|
||||
|
274
src/gui/workspace.py
Normal file
274
src/gui/workspace.py
Normal file
@@ -0,0 +1,274 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2010 Nick Hall
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gui.sidebar import Sidebar
|
||||
from gui.widgets.grampletpane import GrampletPane
|
||||
from gui.views.listview import ListView
|
||||
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.sidebar = Sidebar(self.sidebar_changed)
|
||||
self.hpane = gtk.HPaned()
|
||||
self.vpane = gtk.VPaned()
|
||||
self.gramplet_pane = self.__create_gramplet_pane()
|
||||
self.gramplet_pane.show_all()
|
||||
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()
|
||||
if config.get('interface.filter'):
|
||||
self.sidebar.get_display().show()
|
||||
else:
|
||||
self.sidebar.get_display().hide()
|
||||
self.define_actions()
|
||||
|
||||
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())
|
||||
|
||||
if isinstance(view, ListView):
|
||||
self.add_filter(view.filter_class)
|
||||
|
||||
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>
|
||||
<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("grampletsidebar",
|
||||
self, self.dbstate, self.uistate,
|
||||
column_count=1)
|
||||
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.get_display().show()
|
||||
self.sidebar_changed(self.sidebar.get_page_type(), True)
|
||||
else:
|
||||
self.sidebar.get_display().hide()
|
||||
self.sidebar_changed(None, False)
|
||||
config.set('interface.filter', active)
|
||||
config.save()
|
||||
|
||||
def sidebar_changed(self, page_type, active):
|
||||
"""
|
||||
Called when the sidebar page is changed.
|
||||
"""
|
||||
if isinstance(self.view, ListView):
|
||||
if active and page_type == FILTER_PAGE:
|
||||
self.view.search_bar.hide()
|
||||
else:
|
||||
self.view.search_bar.show()
|
||||
|
||||
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, config.get('interface.filter'))
|
||||
])
|
||||
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.view.set_active()
|
||||
self.gramplet_pane.set_active()
|
||||
|
||||
def set_inactive(self):
|
||||
"""
|
||||
Called when the view is set as inactive.
|
||||
"""
|
||||
self.active = False
|
||||
self.view.set_inactive()
|
||||
self.gramplet_pane.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 view has a configure window.
|
||||
"""
|
||||
return self.view.can_configure()
|
||||
|
||||
def configure(self):
|
||||
"""
|
||||
Open the configure dialog for the view.
|
||||
"""
|
||||
self.view.configure()
|
Reference in New Issue
Block a user