GEPS 014: Plugin registration and management
Also views are now plugins belonging to view category svn: r13528
This commit is contained in:
35
src/plugins/view/Makefile.am
Normal file
35
src/plugins/view/Makefile.am
Normal file
@@ -0,0 +1,35 @@
|
||||
# This is the src/plugins/quickview level Makefile for Gramps
|
||||
# We could use GNU make's ':=' syntax for nice wildcard use,
|
||||
# but that is not necessarily portable.
|
||||
# If not using GNU make, then list all .py files individually
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@/plugins/view
|
||||
|
||||
pkgdata_PYTHON = \
|
||||
eventview.py \
|
||||
familyview.py \
|
||||
geoview.py \
|
||||
geoview.gpr.py \
|
||||
grampletview.py \
|
||||
htmlrenderer \
|
||||
mediaview.py \
|
||||
noteview.py \
|
||||
pedigreeview.py \
|
||||
personview.py \
|
||||
placeview.py \
|
||||
relview.py \
|
||||
repoview.py \
|
||||
sourceview.py \
|
||||
view.gpr.py
|
||||
|
||||
pkgpyexecdir = @pkgpyexecdir@/plugins/view
|
||||
pkgpythondir = @pkgpythondir@/plugins/view
|
||||
|
||||
# Clean up all the byte-compiled files
|
||||
MOSTLYCLEANFILES = *pyc *pyo
|
||||
|
||||
GRAMPS_PY_MODPATH = "../../"
|
||||
|
||||
pycheck:
|
||||
(export PYTHONPATH=$(GRAMPS_PY_MODPATH); \
|
||||
pychecker $(pkgdata_PYTHON));
|
255
src/plugins/view/eventview.py
Normal file
255
src/plugins/view/eventview.py
Normal file
@@ -0,0 +1,255 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-2007 Donald N. Allingham
|
||||
# Copyright (C) 2008 Gary Burton
|
||||
#
|
||||
# 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$
|
||||
|
||||
"""
|
||||
Provide the event view.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
import logging
|
||||
_LOG = logging.getLogger(".plugins.eventview")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import EventModel
|
||||
import Utils
|
||||
import Errors
|
||||
import Bookmarks
|
||||
import config
|
||||
from DdTargets import DdTargets
|
||||
from Editors import EditEvent, DelEventQuery
|
||||
from Filters.SideBar import EventSidebarFilter
|
||||
from gen.plug import CATEGORY_QR_EVENT
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# EventView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class EventView(ListView):
|
||||
"""
|
||||
EventView class, derived from the ListView
|
||||
"""
|
||||
COLUMN_NAMES = [
|
||||
_('Description'),
|
||||
_('ID'),
|
||||
_('Type'),
|
||||
_('Date'),
|
||||
_('Place'),
|
||||
_('Last Changed'),
|
||||
_('Main Participants'),
|
||||
]
|
||||
|
||||
ADD_MSG = _("Add a new event")
|
||||
EDIT_MSG = _("Edit the selected event")
|
||||
DEL_MSG = _("Delete the selected event")
|
||||
FILTER_TYPE = "Event"
|
||||
QR_CATEGORY = CATEGORY_QR_EVENT
|
||||
|
||||
def __init__(self, dbstate, uistate):
|
||||
"""
|
||||
Create the Event View
|
||||
"""
|
||||
signal_map = {
|
||||
'event-add' : self.row_add,
|
||||
'event-update' : self.row_update,
|
||||
'event-delete' : self.row_delete,
|
||||
'event-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
self, _('Events'), dbstate, uistate,
|
||||
EventView.COLUMN_NAMES, len(EventView.COLUMN_NAMES),
|
||||
EventModel,
|
||||
signal_map, dbstate.db.get_event_bookmarks(),
|
||||
Bookmarks.EventBookmarks,
|
||||
multiple=True,
|
||||
filter_class=EventSidebarFilter)
|
||||
|
||||
self.func_list = {
|
||||
'<CONTROL>J' : self.jump,
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
config.connect("interface.filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def column_ord_setfunc(self, clist):
|
||||
self.dbstate.db.set_event_column_order(clist)
|
||||
|
||||
def get_bookmarks(self):
|
||||
"""
|
||||
Return the bookmark object
|
||||
"""
|
||||
return self.dbstate.db.get_event_bookmarks()
|
||||
|
||||
def drag_info(self):
|
||||
"""
|
||||
Indicate that the drag type is an EVENT
|
||||
"""
|
||||
return DdTargets.EVENT
|
||||
|
||||
def column_order(self):
|
||||
"""
|
||||
returns a tuple indicating the column order
|
||||
"""
|
||||
return self.dbstate.db.get_event_column_order()
|
||||
|
||||
def get_stock(self):
|
||||
"""
|
||||
Use the gramps-event stock icon
|
||||
"""
|
||||
return 'gramps-event'
|
||||
|
||||
def ui_definition(self):
|
||||
"""
|
||||
Defines the UI string for UIManager
|
||||
"""
|
||||
return '''<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu action="BookMenu">
|
||||
<placeholder name="AddEditBook">
|
||||
<menuitem action="AddBook"/>
|
||||
<menuitem action="EditBook"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="FileMenu">
|
||||
<placeholder name="LocalExport">
|
||||
<menuitem action="ExportTab"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="EditMenu">
|
||||
<placeholder name="CommonEdit">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<menuitem action="FilterEdit"/>
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
<toolitem action="Remove"/>
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
<separator/>
|
||||
<menu name="QuickReport" action="QuickReport">
|
||||
<menuitem action="Dummy"/>
|
||||
</menu>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def define_actions(self):
|
||||
ListView.define_actions(self)
|
||||
self._add_action('FilterEdit', None, _('Event Filter Editor'),
|
||||
callback=self.filter_editor,)
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor'), callback=self._column_editor,)
|
||||
self._add_action('QuickReport', None,
|
||||
_("Quick View"), None, None, None)
|
||||
self._add_action('Dummy', None,
|
||||
' ', None, None, self.dummy_report)
|
||||
|
||||
def get_handle_from_gramps_id(self, gid):
|
||||
obj = self.dbstate.db.get_event_from_gramps_id(gid)
|
||||
if obj:
|
||||
return obj.get_handle()
|
||||
else:
|
||||
return None
|
||||
|
||||
def _column_editor(self, obj):
|
||||
"""
|
||||
returns a tuple indicating the column order
|
||||
"""
|
||||
import ColumnOrder
|
||||
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Event Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_event_column_order(),
|
||||
EventView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def add(self, obj):
|
||||
try:
|
||||
EditEvent(self.dbstate, self.uistate, [], gen.lib.Event())
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def remove(self, obj):
|
||||
self.remove_selected_objects()
|
||||
|
||||
def remove_object_from_handle(self, handle):
|
||||
person_list = [
|
||||
item[1] for item in
|
||||
self.dbstate.db.find_backlink_handles(handle,['Person']) ]
|
||||
|
||||
family_list = [
|
||||
item[1] for item in
|
||||
self.dbstate.db.find_backlink_handles(handle,['Family']) ]
|
||||
|
||||
object = self.dbstate.db.get_event_from_handle(handle)
|
||||
|
||||
query = DelEventQuery(self.dbstate, self.uistate, object,
|
||||
person_list, family_list)
|
||||
is_used = len(person_list) + len(family_list) > 0
|
||||
return (query, is_used, object)
|
||||
|
||||
def edit(self, obj):
|
||||
for handle in self.selected_handles():
|
||||
event = self.dbstate.db.get_event_from_handle(handle)
|
||||
try:
|
||||
EditEvent(self.dbstate, self.uistate, [], event)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def dummy_report(self, obj):
|
||||
""" For the xml UI definition of popup to work, the submenu
|
||||
Quick Report must have an entry in the xml
|
||||
As this submenu will be dynamically built, we offer a dummy action
|
||||
"""
|
||||
pass
|
||||
|
230
src/plugins/view/familyview.py
Normal file
230
src/plugins/view/familyview.py
Normal file
@@ -0,0 +1,230 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-2006 Donald N. Allingham
|
||||
#
|
||||
# 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$
|
||||
|
||||
"""
|
||||
Family View.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
import logging
|
||||
_LOG = logging.getLogger(".plugins.eventview")
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GNOME/GTK+ modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import FamilyModel
|
||||
import Bookmarks
|
||||
import Errors
|
||||
import config
|
||||
from Filters.SideBar import FamilySidebarFilter
|
||||
from gen.plug import CATEGORY_QR_FAMILY
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# FamilyView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class FamilyView(ListView):
|
||||
|
||||
COLUMN_NAMES = [
|
||||
_('ID'),
|
||||
_('Father'),
|
||||
_('Mother'),
|
||||
_('Relationship'),
|
||||
_('Marriage Date'),
|
||||
_('Last Changed'),
|
||||
]
|
||||
|
||||
ADD_MSG = _("Add a new family")
|
||||
EDIT_MSG = _("Edit the selected family")
|
||||
DEL_MSG = _("Delete the selected family")
|
||||
FILTER_TYPE = "Family"
|
||||
QR_CATEGORY = CATEGORY_QR_FAMILY
|
||||
|
||||
def __init__(self, dbstate, uistate):
|
||||
|
||||
signal_map = {
|
||||
'family-add' : self.row_add,
|
||||
'family-update' : self.row_update,
|
||||
'family-delete' : self.row_delete,
|
||||
'family-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
self, _('Families'), dbstate, uistate,
|
||||
FamilyView.COLUMN_NAMES, len(FamilyView.COLUMN_NAMES),
|
||||
FamilyModel,
|
||||
signal_map, dbstate.db.get_family_bookmarks(),
|
||||
Bookmarks.FamilyBookmarks, filter_class=FamilySidebarFilter)
|
||||
|
||||
self.func_list = {
|
||||
'<CONTROL>J' : self.jump,
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
config.connect("interface.filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def column_ord_setfunc(self, clist):
|
||||
self.dbstate.db.set_family_list_column_order(clist)
|
||||
|
||||
def column_order(self):
|
||||
return self.dbstate.db.get_family_list_column_order()
|
||||
|
||||
def _column_editor(self, obj):
|
||||
import ColumnOrder
|
||||
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Family Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_family_list_column_order(),
|
||||
FamilyView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def get_stock(self):
|
||||
return 'gramps-family'
|
||||
|
||||
def ui_definition(self):
|
||||
return '''<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu action="FileMenu">
|
||||
<placeholder name="LocalExport">
|
||||
<menuitem action="ExportTab"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="EditMenu">
|
||||
<placeholder name="CommonEdit">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<menuitem action="FilterEdit"/>
|
||||
</menu>
|
||||
<menu action="BookMenu">
|
||||
<placeholder name="AddEditBook">
|
||||
<menuitem action="AddBook"/>
|
||||
<menuitem action="EditBook"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
<toolitem action="Remove"/>
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
<separator/>
|
||||
<menu name="QuickReport" action="QuickReport">
|
||||
<menuitem action="Dummy"/>
|
||||
</menu>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def define_actions(self):
|
||||
"""Add the Forward action group to handle the Forward button."""
|
||||
|
||||
ListView.define_actions(self)
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor...'), callback=self._column_editor)
|
||||
|
||||
self._add_action('FilterEdit', None, _('Family Filter Editor'),
|
||||
callback=self.filter_editor,)
|
||||
|
||||
self.all_action = gtk.ActionGroup(self.title + "/FamilyAll")
|
||||
self.all_action.add_actions([
|
||||
('QuickReport', None, _("Quick View"), None, None, None),
|
||||
('Dummy', None, ' ', None, None, self.dummy_report),
|
||||
])
|
||||
self._add_action_group(self.all_action)
|
||||
|
||||
def get_bookmarks(self):
|
||||
return self.dbstate.db.get_family_bookmarks()
|
||||
|
||||
def add_bookmark(self, obj):
|
||||
mlist = self.selected_handles()
|
||||
if mlist:
|
||||
self.bookmarks.add(mlist[0])
|
||||
else:
|
||||
from QuestionDialog import WarningDialog
|
||||
WarningDialog(
|
||||
_("Could Not Set a Bookmark"),
|
||||
_("A bookmark could not be set because "
|
||||
"no one was selected."))
|
||||
|
||||
def add(self, obj):
|
||||
from Editors import EditFamily
|
||||
family = gen.lib.Family()
|
||||
try:
|
||||
EditFamily(self.dbstate, self.uistate, [], family)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def remove(self, obj):
|
||||
from QuestionDialog import QuestionDialog2
|
||||
from Utils import data_recover_msg
|
||||
msg = _('Deleting item will remove it from the database.')
|
||||
msg = msg + '\n' + data_recover_msg
|
||||
q = QuestionDialog2(_('Delete %s?') % _('family'), msg,
|
||||
_('_Delete Item'), _('Cancel'))
|
||||
if q.run():
|
||||
self.uistate.set_busy_cursor(1)
|
||||
import gen.utils
|
||||
for handle in self.selected_handles():
|
||||
gen.utils.remove_family_relationships(self.dbstate.db, handle)
|
||||
self.build_tree()
|
||||
self.uistate.set_busy_cursor(0)
|
||||
|
||||
def edit(self, obj):
|
||||
for handle in self.selected_handles():
|
||||
from Editors import EditFamily
|
||||
family = self.dbstate.db.get_family_from_handle(handle)
|
||||
try:
|
||||
EditFamily(self.dbstate, self.uistate, [], family)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def dummy_report(self, obj):
|
||||
""" For the xml UI definition of popup to work, the submenu
|
||||
Quick Report must have an entry in the xml
|
||||
As this submenu will be dynamically built, we offer a dummy action
|
||||
"""
|
||||
pass
|
69
src/plugins/view/geoview.gpr.py
Normal file
69
src/plugins/view/geoview.gpr.py
Normal file
@@ -0,0 +1,69 @@
|
||||
# encoding:utf-8
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2009 Benny Malengier
|
||||
#
|
||||
# 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$
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Geoview and HtmlView
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
TOOLKIT = NOWEB
|
||||
|
||||
try:
|
||||
import webkit
|
||||
TOOLKIT = WEBKIT
|
||||
except:
|
||||
try:
|
||||
import gtkmozembed
|
||||
TOOLKIT = MOZILLA
|
||||
except:
|
||||
pass
|
||||
|
||||
#no interfaces present, we do not register these plugins
|
||||
if not (TOOLKIT == NOWEB):
|
||||
register(VIEW,
|
||||
id = 'geoview',
|
||||
name = _("Geographic View"),
|
||||
description = _("The view showing events on an interactive internet map "
|
||||
"(internet connection needed"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'geoview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_GEO,
|
||||
viewclass = 'GeoView',
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'htmlview',
|
||||
name = _("Html View"),
|
||||
description = _("A view allowing to see html pages embedded in GRAMPS"),
|
||||
version = '1.0',
|
||||
status = UNSTABLE,
|
||||
fname = 'htmlrenderer.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_MISC,
|
||||
viewclass = 'HtmlView',
|
||||
)
|
1855
src/plugins/view/geoview.py
Normal file
1855
src/plugins/view/geoview.py
Normal file
File diff suppressed because it is too large
Load Diff
1242
src/plugins/view/grampletview.py
Normal file
1242
src/plugins/view/grampletview.py
Normal file
File diff suppressed because it is too large
Load Diff
652
src/plugins/view/htmlrenderer.py
Normal file
652
src/plugins/view/htmlrenderer.py
Normal file
@@ -0,0 +1,652 @@
|
||||
# -*- python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2007-2009 Serge Noiraud
|
||||
# Copyright (C) 2008 Benny Malengier
|
||||
#
|
||||
# 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: GeoView.py 12995 2009-08-13 21:59:59Z noirauds $
|
||||
|
||||
"""
|
||||
Html Renderer
|
||||
Can use the Webkit or Gecko ( Mozilla ) library
|
||||
"""
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
import os
|
||||
import locale
|
||||
import urlparse
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps Modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gui.views.pageview import PageView
|
||||
import Utils
|
||||
import config
|
||||
from const import TEMP_DIR
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
def get_identity():
|
||||
if Utils.lin():
|
||||
platform = "X11"
|
||||
elif Utils.win():
|
||||
platform = "Windows"
|
||||
elif Utils.mac():
|
||||
platform = "Macintosh"
|
||||
else:
|
||||
platform = "Unknown"
|
||||
(lang_country, modifier ) = locale.getlocale()
|
||||
lang = lang_country.replace('_','-')
|
||||
#lang += ", " + lang_country.split('_')[0]
|
||||
return "Mozilla/5.0 (%s; U; %s) Gramps/3.2" % ( platform, lang)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Constants
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
# I think we should set the two following variable in const.py
|
||||
# They are used only with gtkmozembed.
|
||||
MOZEMBED_PATH = TEMP_DIR
|
||||
MOZEMBED_SUBPATH = Utils.get_empty_tempdir('mozembed_gramps')
|
||||
GEOVIEW_SUBPATH = Utils.get_empty_tempdir('geoview')
|
||||
NOWEB = 0
|
||||
WEBKIT = 1
|
||||
MOZILLA = 2
|
||||
KITNAME = [ "None", "WebKit", "Mozilla" ]
|
||||
URL_SEP = '/'
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# What Web interfaces ?
|
||||
#
|
||||
# We use firstly webkit if it is present. If not, we use gtkmozembed.
|
||||
# If no web interface is present, we don't register GeoView in the gui.
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
TOOLKIT = NOWEB
|
||||
|
||||
try:
|
||||
import webkit
|
||||
TOOLKIT = WEBKIT
|
||||
except:
|
||||
try:
|
||||
import gtkmozembed
|
||||
TOOLKIT = MOZILLA
|
||||
except:
|
||||
pass
|
||||
|
||||
#no interfaces present, raise Error so that options for GeoView do not show
|
||||
if TOOLKIT == NOWEB :
|
||||
raise ImportError, 'No GTK html plugin found'
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Renderer
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
#class Renderer(object):
|
||||
class Renderer():
|
||||
"""
|
||||
Renderer renders the webpage. Several backend implementations are
|
||||
possible
|
||||
"""
|
||||
def __init__(self):
|
||||
self.window = None
|
||||
|
||||
def get_window(self):
|
||||
"""
|
||||
Returns a container class with the widget that contains browser
|
||||
window
|
||||
"""
|
||||
return self.window
|
||||
|
||||
def get_uri(self):
|
||||
"""
|
||||
Get the current url
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def show_all(self):
|
||||
"""
|
||||
show all in the main window.
|
||||
"""
|
||||
self.window.show_all()
|
||||
|
||||
def open(self, url):
|
||||
"""
|
||||
open the webpage at url
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def refresh(self):
|
||||
"""
|
||||
We need to reload the page.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def go_back(self):
|
||||
"""
|
||||
Go to the previous page.
|
||||
"""
|
||||
self.window.go_back()
|
||||
|
||||
def can_go_back(self):
|
||||
"""
|
||||
is the browser able to go backward ?
|
||||
"""
|
||||
return self.window.can_go_back()
|
||||
|
||||
def go_forward(self):
|
||||
"""
|
||||
Go to the next page.
|
||||
"""
|
||||
self.window.go_forward()
|
||||
|
||||
def can_go_forward(self):
|
||||
"""
|
||||
is the browser able to go forward ?
|
||||
"""
|
||||
return self.window.can_go_forward()
|
||||
|
||||
def get_title(self):
|
||||
"""
|
||||
We need to get the html title page.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def execute_script(self, url):
|
||||
"""
|
||||
execute javascript in the current html page
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def page_loaded(self, *args):
|
||||
"""
|
||||
The page is completely loaded.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def set_button_sensitivity(self):
|
||||
"""
|
||||
We must set the back and forward button in the HtmlView class.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Renderer with WebKit
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class RendererWebkit(Renderer):
|
||||
"""
|
||||
Implementation of Renderer with Webkit
|
||||
"""
|
||||
def __init__(self):
|
||||
Renderer.__init__(self)
|
||||
self.window = webkit.WebView()
|
||||
try:
|
||||
self.window.set_custom_encoding('utf-8') # needs webkit 1.1.10
|
||||
except: # pylint: disable-msg=W0702
|
||||
pass
|
||||
settings = self.window.get_settings()
|
||||
try:
|
||||
proxy = os.environ['http_proxy']
|
||||
# webkit use libsoup instead of libcurl.
|
||||
#if proxy:
|
||||
# settings.set_property("use-proxy", True)
|
||||
except: # pylint: disable-msg=W0702
|
||||
pass
|
||||
#settings.set_property("ident-string", get_identity())
|
||||
# do we need it ? Yes if webkit avoid to use local files for security
|
||||
## The following available starting from WebKitGTK+ 1.1.13
|
||||
#settings.set_property("enable-universal-access-from-file-uris", True)
|
||||
self.browser = WEBKIT
|
||||
self.title = None
|
||||
self.frame = self.window.get_main_frame()
|
||||
self.frame.connect("load-done", self.page_loaded)
|
||||
self.frame.connect("title-changed", self.get_title)
|
||||
self.fct = None
|
||||
|
||||
def page_loaded(self, *args):
|
||||
"""
|
||||
We just loaded one page in the browser.
|
||||
Set the button sensitivity
|
||||
"""
|
||||
self.set_button_sensitivity()
|
||||
|
||||
def set_button_sensitivity(self):
|
||||
"""
|
||||
We must set the back and forward button in the HtmlView class.
|
||||
"""
|
||||
self.fct()
|
||||
|
||||
def open(self, url):
|
||||
"""
|
||||
We need to load the page in the browser.
|
||||
"""
|
||||
self.window.open(url)
|
||||
|
||||
def refresh(self):
|
||||
"""
|
||||
We need to reload the page in the browser.
|
||||
"""
|
||||
self.window.reload()
|
||||
|
||||
def get_title(self, *args):
|
||||
"""
|
||||
We need to get the html title page.
|
||||
"""
|
||||
self.title = self.frame.get_title()
|
||||
|
||||
def execute_script(self, url):
|
||||
"""
|
||||
We need to execute a javascript function into the browser
|
||||
"""
|
||||
self.window.execute_script(url)
|
||||
|
||||
def get_uri(self):
|
||||
"""
|
||||
What is the uri loaded in the browser ?
|
||||
"""
|
||||
return self.window.get_main_frame().get_uri()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# The Mozilla or Gecko Renderer class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class RendererMozilla(Renderer):
|
||||
"""
|
||||
Implementation of Renderer with gtkmozembed
|
||||
"""
|
||||
def __init__(self):
|
||||
Renderer.__init__(self)
|
||||
if hasattr(gtkmozembed, 'set_profile_path'):
|
||||
set_profile_path = gtkmozembed.set_profile_path
|
||||
else:
|
||||
set_profile_path = gtkmozembed.gtk_moz_embed_set_profile_path
|
||||
set_profile_path(MOZEMBED_PATH, MOZEMBED_SUBPATH)
|
||||
self.__set_mozembed_proxy()
|
||||
self.window = gtkmozembed.MozEmbed()
|
||||
self.browser = MOZILLA
|
||||
self.title = None
|
||||
self.handler = self.window.connect("net-stop", self.page_loaded)
|
||||
self.window.connect("title", self.get_title)
|
||||
self.fct = None
|
||||
|
||||
def page_loaded(self, *args):
|
||||
"""
|
||||
We just loaded one page in the browser.
|
||||
Set the button sensitivity
|
||||
"""
|
||||
self.set_button_sensitivity()
|
||||
|
||||
def set_button_sensitivity(self):
|
||||
"""
|
||||
We must set the back and forward button in the HtmlView class.
|
||||
"""
|
||||
self.fct()
|
||||
|
||||
def open(self, url):
|
||||
"""
|
||||
We need to load the page in the browser.
|
||||
"""
|
||||
self.window.load_url(url)
|
||||
|
||||
def get_title(self, *args):
|
||||
"""
|
||||
We need to get the html title page.
|
||||
"""
|
||||
self.title = self.window.get_title()
|
||||
|
||||
def execute_script(self, url):
|
||||
"""
|
||||
We need to execute a javascript function into the browser
|
||||
"""
|
||||
self.window.load_url(url)
|
||||
|
||||
def get_uri(self):
|
||||
"""
|
||||
What is the uri loaded in the browser ?
|
||||
"""
|
||||
return self.window.get_location()
|
||||
|
||||
def refresh(self):
|
||||
"""
|
||||
We need to reload the page in the browser.
|
||||
"""
|
||||
self.window.reload(0)
|
||||
|
||||
def __set_mozembed_proxy(self):
|
||||
"""
|
||||
Try to see if we have some proxy environment variable.
|
||||
http_proxy in our case.
|
||||
The standard format is : http://[user:password@]proxy:port/
|
||||
"""
|
||||
try:
|
||||
proxy = os.environ['http_proxy']
|
||||
if proxy:
|
||||
host_port = None
|
||||
prefs = open(os.path.join(MOZEMBED_SUBPATH,
|
||||
"prefs.js"),
|
||||
"w+")
|
||||
parts = urlparse.urlparse(proxy)
|
||||
if not parts[0] or parts[0] == 'http':
|
||||
host_port = parts[1]
|
||||
hport = host_port.split(':')
|
||||
host = hport[0].strip()
|
||||
if host:
|
||||
try:
|
||||
port = int(hport[1])
|
||||
except:
|
||||
user = host
|
||||
uprox = hport[1].split('@')
|
||||
password = uprox[0]
|
||||
host = uprox[1]
|
||||
port = int(hport[2])
|
||||
if port and host:
|
||||
port = str(port)
|
||||
prefs.write('user_pref("network.proxy')
|
||||
prefs.write('.type", 1);\r\n')
|
||||
prefs.write('user_pref("network.proxy')
|
||||
prefs.write('.http", "'+host+'");\r\n')
|
||||
prefs.write('user_pref("network.proxy')
|
||||
prefs.write('.http_port", '+port+');\r\n')
|
||||
prefs.write('user_pref("network.proxy')
|
||||
prefs.write('.no_proxies_on",')
|
||||
prefs.write(' "127.0.0.1,localhost,localhost')
|
||||
prefs.write('.localdomain");\r\n')
|
||||
prefs.write('user_pref("network.proxy')
|
||||
prefs.write('.share_proxy_settings", true);\r\n')
|
||||
prefs.write('user_pref("network.http')
|
||||
prefs.write('.proxy.pipelining", true);\r\n')
|
||||
prefs.write('user_pref("network.http')
|
||||
prefs.write('.proxy.keep-alive", true);\r\n')
|
||||
prefs.write('user_pref("network.http')
|
||||
prefs.write('.proxy.version", 1.1);\r\n')
|
||||
prefs.write('user_pref("network.http')
|
||||
prefs.write('.sendRefererHeader, 0);\r\n')
|
||||
prefs.write('user_pref("general.useragent')
|
||||
prefs.write('.extra.firefox, "Mozilla/5.0");\r\n')
|
||||
prefs.write('user_pref("general.useragent')
|
||||
prefs.write('.locale, "fr");\r\n')
|
||||
prefs.close()
|
||||
except:
|
||||
try: # trying to remove pref.js in case of proxy change.
|
||||
os.remove(os.path.join(MOZEMBED_SUBPATH, "prefs.js"))
|
||||
except:
|
||||
pass
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# HtmlView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class HtmlView(PageView):
|
||||
"""
|
||||
HtmlView is a view showing a top widget with controls, and a bottom part
|
||||
with an embedded webbrowser showing a given URL
|
||||
"""
|
||||
|
||||
def __init__(self, dbstate, uistate, title=_('HtmlView')):
|
||||
PageView.__init__(self, title, dbstate, uistate)
|
||||
self.dbstate = dbstate
|
||||
self.back_action = None
|
||||
self.forward_action = None
|
||||
self.renderer = None
|
||||
self.urlfield = ""
|
||||
self.htmlfile = ""
|
||||
self.table = ""
|
||||
self.browser = NOWEB
|
||||
self.bootstrap_handler = None
|
||||
self.box = None
|
||||
|
||||
def build_widget(self):
|
||||
"""
|
||||
Builds the interface and returns a gtk.Container type that
|
||||
contains the interface. This containter will be inserted into
|
||||
a gtk.Notebook page.
|
||||
"""
|
||||
self.box = gtk.VBox(False, 4)
|
||||
#top widget at the top
|
||||
self.box.pack_start(self.top_widget(), False, False, 0 )
|
||||
#web page under it in a scrolled window
|
||||
self.table = gtk.Table(1, 1, False)
|
||||
frame = gtk.ScrolledWindow(None, None)
|
||||
frame.set_shadow_type(gtk.SHADOW_NONE)
|
||||
frame.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
frame.add_with_viewport(self.table)
|
||||
self.bootstrap_handler = self.box.connect("size-request",
|
||||
self.init_parent_signals_for_map)
|
||||
self.table.get_parent().set_shadow_type(gtk.SHADOW_NONE)
|
||||
self.table.set_row_spacings(1)
|
||||
self.table.set_col_spacings(0)
|
||||
if (TOOLKIT == WEBKIT) :
|
||||
# We use webkit
|
||||
self.renderer = RendererWebkit()
|
||||
elif (TOOLKIT == MOZILLA) :
|
||||
# We use gtkmozembed
|
||||
self.renderer = RendererMozilla()
|
||||
self.table.add(self.renderer.get_window())
|
||||
self.box.pack_start(frame, True, True, 0)
|
||||
# this is used to activate the back and forward button
|
||||
# from the renderer class.
|
||||
self.renderer.fct = self.set_button_sensitivity
|
||||
self.renderer.show_all()
|
||||
#load a welcome html page
|
||||
urlhelp = self._create_start_page()
|
||||
self.open(urlhelp)
|
||||
return self.box
|
||||
|
||||
def top_widget(self):
|
||||
"""
|
||||
The default class gives a widget where user can type an url
|
||||
"""
|
||||
hbox = gtk.HBox(False, 4)
|
||||
self.urlfield = gtk.Entry()
|
||||
self.urlfield.set_text(config.get("htmlview.start-url"))
|
||||
self.urlfield.connect('activate', self._on_activate)
|
||||
hbox.pack_start(self.urlfield, True, True, 4)
|
||||
button = gtk.Button(stock=gtk.STOCK_APPLY)
|
||||
button.connect('clicked', self._on_activate)
|
||||
hbox.pack_start(button, False, False, 4)
|
||||
return hbox
|
||||
|
||||
def set_button_sensitivity(self):
|
||||
"""
|
||||
Set the backward and forward button in accordance to the browser.
|
||||
"""
|
||||
self.forward_action.set_sensitive(self.renderer.can_go_forward())
|
||||
self.back_action.set_sensitive(self.renderer.can_go_back())
|
||||
|
||||
def open(self, url):
|
||||
"""
|
||||
open an url
|
||||
"""
|
||||
self.renderer.open(url)
|
||||
|
||||
def go_back(self, button):
|
||||
"""
|
||||
Go to the previous loaded url.
|
||||
"""
|
||||
self.renderer.go_back()
|
||||
self.set_button_sensitivity()
|
||||
self.external_uri()
|
||||
|
||||
def go_forward(self, button):
|
||||
"""
|
||||
Go to the next loaded url.
|
||||
"""
|
||||
self.renderer.go_forward()
|
||||
self.set_button_sensitivity()
|
||||
self.external_uri()
|
||||
|
||||
def refresh(self, button):
|
||||
"""
|
||||
Force to reload the page.
|
||||
"""
|
||||
self.renderer.refresh()
|
||||
|
||||
def external_uri(self):
|
||||
"""
|
||||
used to resize or not resize depending on external or local file.
|
||||
"""
|
||||
uri = self.renderer.get_uri()
|
||||
|
||||
def _on_activate(self, nobject):
|
||||
"""
|
||||
Here when we activate the url button.
|
||||
"""
|
||||
url = self.urlfield.get_text()
|
||||
if url.find('://') == -1:
|
||||
url = 'http://'+ url
|
||||
self.open(url)
|
||||
|
||||
def build_tree(self):
|
||||
"""
|
||||
Rebuilds the current display. Called from ViewManager
|
||||
"""
|
||||
pass #htmlview is build on click and startup
|
||||
|
||||
def get_stock(self):
|
||||
"""
|
||||
Returns the name of the stock icon to use for the display.
|
||||
This assumes that this icon has already been registered with
|
||||
GNOME as a stock icon.
|
||||
"""
|
||||
return 'gramps-geo'
|
||||
|
||||
def ui_definition(self):
|
||||
"""
|
||||
Specifies the UIManager XML code that defines the menus and buttons
|
||||
associated with the interface.
|
||||
"""
|
||||
return '''<ui>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonNavigation">
|
||||
<toolitem action="Back"/>
|
||||
<toolitem action="Forward"/>
|
||||
<toolitem action="Refresh"/>
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
</ui>'''
|
||||
|
||||
def define_actions(self):
|
||||
"""
|
||||
Required define_actions function for PageView. Builds the action
|
||||
group information required.
|
||||
"""
|
||||
HtmlView._define_actions_fw_bw(self)
|
||||
|
||||
def _define_actions_fw_bw(self):
|
||||
"""
|
||||
prepare the forward and backward buttons.
|
||||
add the Backward action to handle the Backward button
|
||||
accel doesn't work in webkit and gtkmozembed !
|
||||
we must do that ...
|
||||
"""
|
||||
self.back_action = gtk.ActionGroup(self.title + '/Back')
|
||||
self.back_action.add_actions([
|
||||
('Back', gtk.STOCK_GO_BACK, _("_Back"),
|
||||
"<ALT>Left", _("Go to the previous page in the history"),
|
||||
self.go_back)
|
||||
])
|
||||
self._add_action_group(self.back_action)
|
||||
# add the Forward action to handle the Forward button
|
||||
self.forward_action = gtk.ActionGroup(self.title + '/Forward')
|
||||
self.forward_action.add_actions([
|
||||
('Forward', gtk.STOCK_GO_FORWARD, _("_Forward"),
|
||||
"<ALT>Right", _("Go to the next page in the history"),
|
||||
self.go_forward)
|
||||
])
|
||||
self._add_action_group(self.forward_action)
|
||||
# add the Refresh action to handle the Refresh button
|
||||
self._add_action('Refresh', gtk.STOCK_REFRESH, _("_Refresh"),
|
||||
callback=self.refresh,
|
||||
accel="<Ctl>R",
|
||||
tip=_("Stop and reload the page."))
|
||||
|
||||
def init_parent_signals_for_map(self, widget, event):
|
||||
"""
|
||||
Required to properly bootstrap the signal handlers.
|
||||
This handler is connected by build_widget.
|
||||
After the outside ViewManager has placed this widget we are
|
||||
able to access the parent container.
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_renderer(self):
|
||||
"""
|
||||
return the renderer : Webkit, Mozilla or None
|
||||
"""
|
||||
#return self.browser
|
||||
return KITNAME[self.browser]
|
||||
|
||||
def _create_start_page(self):
|
||||
"""
|
||||
This command creates a default start page, and returns the URL of
|
||||
this page.
|
||||
"""
|
||||
tmpdir = GEOVIEW_SUBPATH
|
||||
data = """
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" \
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" >
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
|
||||
<title>%(title)s</title>
|
||||
</head>
|
||||
<body >
|
||||
<H4>%(content)s</H4>
|
||||
</body>
|
||||
</html>
|
||||
""" % { 'height' : 600,
|
||||
'title' : _('Start page for the Html View'),
|
||||
'content': _('Type a webpage address at the top, and hit'
|
||||
' the execute button to load a webpage in this'
|
||||
' page\n<br>\n'
|
||||
'For example: <b>http://gramps-project.org</p>')
|
||||
}
|
||||
filename = os.path.join(tmpdir, 'startpage.html')
|
||||
ufd = file(filename, "w+")
|
||||
ufd.write(data)
|
||||
ufd.close()
|
||||
return urlparse.urlunsplit(('file', '',
|
||||
URL_SEP.join(filename.split(os.sep)),
|
||||
'', ''))
|
||||
|
401
src/plugins/view/mediaview.py
Normal file
401
src/plugins/view/mediaview.py
Normal file
@@ -0,0 +1,401 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-2006 Donald N. Allingham
|
||||
# Copyright (C) 2008 Gary Burton
|
||||
#
|
||||
# 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$
|
||||
|
||||
"""
|
||||
Media View.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
import urlparse
|
||||
import os
|
||||
import cPickle as pickle
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gui.utils import open_file_with_default_application
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import MediaModel
|
||||
import ThumbNails
|
||||
import const
|
||||
import config
|
||||
import Utils
|
||||
import Bookmarks
|
||||
import Mime
|
||||
import gen.lib
|
||||
from Editors import EditMedia, DeleteMediaQuery
|
||||
import Errors
|
||||
from Filters.SideBar import MediaSidebarFilter
|
||||
from DdTargets import DdTargets
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# MediaView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class MediaView(ListView):
|
||||
"""
|
||||
Provide the Media View interface on the GRAMPS main window. This allows
|
||||
people to manage all media items in their database. This is very similar
|
||||
to the other list based views, with the exception that it also has a
|
||||
thumbnail image at the top of the view that must be updated when the
|
||||
selection changes or when the selected media object changes.
|
||||
"""
|
||||
|
||||
COLUMN_NAMES = [
|
||||
_('Title'),
|
||||
_('ID'),
|
||||
_('Type'),
|
||||
_('Path'),
|
||||
_('Last Changed'),
|
||||
_('Date'),
|
||||
]
|
||||
|
||||
ADD_MSG = _("Add a new media object")
|
||||
EDIT_MSG = _("Edit the selected media object")
|
||||
DEL_MSG = _("Delete the selected media object")
|
||||
FILTER_TYPE = 'MediaObject'
|
||||
|
||||
_DND_TYPE = DdTargets.URI_LIST
|
||||
|
||||
def __init__(self, dbstate, uistate):
|
||||
|
||||
signal_map = {
|
||||
'media-add' : self.row_add,
|
||||
'media-update' : self.row_update,
|
||||
'media-delete' : self.row_delete,
|
||||
'media-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
self, _('Media'), dbstate, uistate,
|
||||
MediaView.COLUMN_NAMES, len(MediaView.COLUMN_NAMES),
|
||||
MediaModel,
|
||||
signal_map, dbstate.db.get_media_bookmarks(),
|
||||
Bookmarks.MediaBookmarks, filter_class=MediaSidebarFilter,
|
||||
multiple=True)
|
||||
|
||||
self.func_list = {
|
||||
'<CONTROL>J' : self.jump,
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
config.connect("interface.filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def column_ord_setfunc(self, clist):
|
||||
self.dbstate.db.set_media_column_order(clist)
|
||||
|
||||
def _set_dnd(self):
|
||||
"""
|
||||
Set up drag-n-drop. The source and destination are set by calling .target()
|
||||
on the _DND_TYPE. Obviously, this means that there must be a _DND_TYPE
|
||||
variable defined that points to an entry in DdTargets.
|
||||
"""
|
||||
|
||||
dnd_types = [ self._DND_TYPE.target() ]
|
||||
|
||||
self.list.drag_dest_set(gtk.DEST_DEFAULT_ALL, dnd_types,
|
||||
gtk.gdk.ACTION_COPY)
|
||||
self.list.drag_source_set(gtk.gdk.BUTTON1_MASK,
|
||||
[self._DND_TYPE.target()],
|
||||
gtk.gdk.ACTION_COPY)
|
||||
self.list.connect('drag_data_get', self.drag_data_get)
|
||||
self.list.connect('drag_data_received', self.drag_data_received)
|
||||
|
||||
def drag_data_get(self, widget, context, sel_data, info, time):
|
||||
"""
|
||||
Provide the drag_data_get function, which passes a tuple consisting of:
|
||||
|
||||
1) Drag type defined by the .drag_type field specified by the value
|
||||
assigned to _DND_TYPE
|
||||
2) The id value of this object, used for the purpose of determining
|
||||
the source of the object. If the source of the object is the same
|
||||
as the object, we are doing a reorder instead of a normal drag
|
||||
and drop
|
||||
3) Pickled data. The pickled version of the selected object
|
||||
4) Source row. Used for a reorder to determine the original position
|
||||
of the object
|
||||
"""
|
||||
|
||||
selected_ids = self.selected_handles()
|
||||
if selected_ids:
|
||||
data = (self.drag_info().drag_type, id(self), selected_ids[0], 0)
|
||||
sel_data.set(sel_data.target, 8, pickle.dumps(data))
|
||||
|
||||
def drag_info(self):
|
||||
"""
|
||||
Return the type of DND targetst that this view will accept. For Media
|
||||
View, we will accept media objects.
|
||||
"""
|
||||
return DdTargets.MEDIAOBJ
|
||||
|
||||
def find_index(self, obj):
|
||||
"""
|
||||
returns the index of the object within the associated data
|
||||
"""
|
||||
return self.model.indexlist[obj]
|
||||
|
||||
def drag_data_received(self, widget, context, x, y, sel_data, info, time):
|
||||
"""
|
||||
Handle the standard gtk interface for drag_data_received.
|
||||
|
||||
If the selection data is define, extract the value from sel_data.data,
|
||||
and decide if this is a move or a reorder.
|
||||
"""
|
||||
if sel_data and sel_data.data:
|
||||
cleaned_string = sel_data.data.replace('\0', ' ')
|
||||
cleaned_string = cleaned_string.replace("\r", " ").strip()
|
||||
data_list = Utils.fix_encoding(cleaned_string).split('\n')
|
||||
for d in [item.strip() for item in data_list]:
|
||||
protocol, site, mfile, j, k, l = urlparse.urlparse(d)
|
||||
if protocol == "file":
|
||||
name = Utils.fix_encoding(mfile)
|
||||
mime = Mime.get_type(name)
|
||||
if not Mime.is_valid_type(mime):
|
||||
return
|
||||
photo = gen.lib.MediaObject()
|
||||
photo.set_path(name)
|
||||
photo.set_mime_type(mime)
|
||||
basename = os.path.basename(name)
|
||||
(root, ext) = os.path.splitext(basename)
|
||||
photo.set_description(root)
|
||||
trans = self.dbstate.db.transaction_begin()
|
||||
self.dbstate.db.add_object(photo, trans)
|
||||
self.dbstate.db.transaction_commit(trans,
|
||||
_("Drag Media Object"))
|
||||
widget.emit_stop_by_name('drag_data_received')
|
||||
|
||||
def get_bookmarks(self):
|
||||
"""
|
||||
Return the booksmarks associated with this view
|
||||
"""
|
||||
return self.dbstate.db.get_media_bookmarks()
|
||||
|
||||
def define_actions(self):
|
||||
"""
|
||||
Defines the UIManager actions specific to Media View. We need to make
|
||||
sure that the common List View actions are defined as well, so we
|
||||
call the parent function.
|
||||
"""
|
||||
ListView.define_actions(self)
|
||||
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor'), callback=self._column_editor)
|
||||
self._add_action('FilterEdit', None, _('Media Filter Editor'),
|
||||
callback=self.filter_editor)
|
||||
self._add_action('OpenMedia', 'gramps-viewmedia', _('View'),
|
||||
tip=_("View in the default viewer"),
|
||||
callback=self.view_media)
|
||||
|
||||
def view_media(self, obj):
|
||||
"""
|
||||
Launch external viewers for the selected objects.
|
||||
"""
|
||||
for handle in self.selected_handles():
|
||||
ref_obj = self.dbstate.db.get_object_from_handle(handle)
|
||||
mpath = Utils.media_path_full(self.dbstate.db, ref_obj.get_path())
|
||||
open_file_with_default_application(mpath)
|
||||
|
||||
def _column_editor(self, obj):
|
||||
"""
|
||||
Start the column editor dialog
|
||||
"""
|
||||
import ColumnOrder
|
||||
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Media Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_media_column_order(),
|
||||
MediaView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def column_order(self):
|
||||
"""
|
||||
Get the column order from the database
|
||||
"""
|
||||
return self.dbstate.db.get_media_column_order()
|
||||
|
||||
def get_stock(self):
|
||||
"""
|
||||
Return the icon for this view
|
||||
"""
|
||||
return 'gramps-media'
|
||||
|
||||
def build_widget(self):
|
||||
"""
|
||||
Builds the View from GTK components
|
||||
"""
|
||||
base = ListView.build_widget(self)
|
||||
vbox = gtk.VBox()
|
||||
vbox.set_border_width(0)
|
||||
vbox.set_spacing(4)
|
||||
|
||||
self.image = gtk.Image()
|
||||
self.image.set_size_request(int(const.THUMBSCALE),
|
||||
int(const.THUMBSCALE))
|
||||
ebox = gtk.EventBox()
|
||||
ebox.add(self.image)
|
||||
ebox.connect('button-press-event', self.button_press_event)
|
||||
ebox.set_tooltip_text(
|
||||
_('Double click image to view in an external viewer'))
|
||||
vbox.pack_start(ebox, False)
|
||||
vbox.pack_start(base, True)
|
||||
|
||||
self.selection.connect('changed', self.row_change)
|
||||
self._set_dnd()
|
||||
return vbox
|
||||
|
||||
def button_press_event(self, obj, event):
|
||||
"""
|
||||
Event handler that catches a double click, and and launches a viewer for
|
||||
the selected object.
|
||||
"""
|
||||
if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
|
||||
self.view_media(obj)
|
||||
|
||||
def row_update(self, obj):
|
||||
"""
|
||||
Update the data in the row. we override this because the Media View adds
|
||||
additional functionality to the normal List View. The Media View may
|
||||
have to update the thumbnail image. So, we call the parent task to
|
||||
handle the normal operation, then call row_change to make sure that
|
||||
the thumbnail is updated properly if needed.
|
||||
"""
|
||||
ListView.row_update(self, obj)
|
||||
if self.active:
|
||||
self.row_change(obj)
|
||||
|
||||
def row_change(self, obj):
|
||||
"""
|
||||
Update the thumbnail on a row change. If nothing is selected, clear
|
||||
the thumbnail image.
|
||||
"""
|
||||
handle = self.first_selected()
|
||||
if not handle:
|
||||
self.image.clear()
|
||||
else:
|
||||
obj = self.dbstate.db.get_object_from_handle(handle)
|
||||
pix = ThumbNails.get_thumbnail_image(
|
||||
Utils.media_path_full(self.dbstate.db, obj.get_path()))
|
||||
self.image.set_from_pixbuf(pix)
|
||||
|
||||
def ui_definition(self):
|
||||
"""
|
||||
Return the UIManager XML description of the menus
|
||||
"""
|
||||
return '''<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu action="FileMenu">
|
||||
<placeholder name="LocalExport">
|
||||
<menuitem action="ExportTab"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="EditMenu">
|
||||
<placeholder name="CommonEdit">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<menuitem action="FilterEdit"/>
|
||||
</menu>
|
||||
<menu action="BookMenu">
|
||||
<placeholder name="AddEditBook">
|
||||
<menuitem action="AddBook"/>
|
||||
<menuitem action="EditBook"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
<toolitem action="Remove"/>
|
||||
</placeholder>
|
||||
<separator/>
|
||||
<toolitem action="OpenMedia"/>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="OpenMedia"/>
|
||||
<menuitem action="Remove"/>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def add(self, obj):
|
||||
"""Add a new media object to the media list"""
|
||||
try:
|
||||
EditMedia(self.dbstate, self.uistate, [], gen.lib.MediaObject())
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def remove(self, obj):
|
||||
self.remove_selected_objects()
|
||||
|
||||
def remove_object_from_handle(self, handle):
|
||||
"""
|
||||
Remove the selected objects from the database after getting
|
||||
user verification.
|
||||
"""
|
||||
the_lists = Utils.get_media_referents(handle, self.dbstate.db)
|
||||
object = self.dbstate.db.get_object_from_handle(handle)
|
||||
query = DeleteMediaQuery(self.dbstate, self.uistate, handle, the_lists)
|
||||
is_used = any(the_lists)
|
||||
return (query, is_used, object)
|
||||
|
||||
def edit(self, obj):
|
||||
"""
|
||||
Edit the selected objects in the EditMedia dialog
|
||||
"""
|
||||
for handle in self.selected_handles():
|
||||
object = self.dbstate.db.get_object_from_handle(handle)
|
||||
try:
|
||||
EditMedia(self.dbstate, self.uistate, [], object)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def get_handle_from_gramps_id(self, gid):
|
||||
"""
|
||||
returns the handle of the specified object
|
||||
"""
|
||||
obj = self.dbstate.db.get_object_from_gramps_id(gid)
|
||||
if obj:
|
||||
return obj.get_handle()
|
||||
else:
|
||||
return None
|
218
src/plugins/view/noteview.py
Normal file
218
src/plugins/view/noteview.py
Normal file
@@ -0,0 +1,218 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-2006 Donald N. Allingham
|
||||
# Copyright (C) 2008 Gary Burton
|
||||
#
|
||||
# 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$
|
||||
|
||||
"""
|
||||
Note View.
|
||||
"""
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
import logging
|
||||
_LOG = logging.getLogger(".plugins.noteview")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import NoteModel
|
||||
import Utils
|
||||
import Errors
|
||||
import Bookmarks
|
||||
import config
|
||||
import ColumnOrder
|
||||
from gen.lib import Note
|
||||
from DdTargets import DdTargets
|
||||
from Filters.SideBar import NoteSidebarFilter
|
||||
from Editors import EditNote, DeleteNoteQuery
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# NoteView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class NoteView(ListView):
|
||||
|
||||
COLUMN_NAMES = [
|
||||
_('Preview'),
|
||||
_('ID'),
|
||||
_('Type'),
|
||||
_('Marker'),
|
||||
]
|
||||
|
||||
ADD_MSG = _("Add a new note")
|
||||
EDIT_MSG = _("Edit the selected note")
|
||||
DEL_MSG = _("Delete the selected note")
|
||||
FILTER_TYPE = "Note"
|
||||
|
||||
def __init__(self, dbstate, uistate):
|
||||
|
||||
signal_map = {
|
||||
'note-add' : self.row_add,
|
||||
'note-update' : self.row_update,
|
||||
'note-delete' : self.row_delete,
|
||||
'note-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
self.func_list = {
|
||||
'<CONTROL>J' : self.jump,
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
self, _('Notes'), dbstate, uistate, NoteView.COLUMN_NAMES,
|
||||
len(NoteView.COLUMN_NAMES), NoteModel, signal_map,
|
||||
dbstate.db.get_note_bookmarks(),
|
||||
Bookmarks.NoteBookmarks,
|
||||
filter_class=NoteSidebarFilter,
|
||||
multiple=True)
|
||||
|
||||
config.connect("interface.filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def column_ord_setfunc(self, clist):
|
||||
self.dbstate.db.set_note_column_order(clist)
|
||||
|
||||
def get_bookmarks(self):
|
||||
"""
|
||||
Return the bookmark object
|
||||
"""
|
||||
return self.dbstate.db.get_note_bookmarks()
|
||||
|
||||
def drag_info(self):
|
||||
"""
|
||||
Indicate that the drag type is an EVENT
|
||||
"""
|
||||
return DdTargets.NOTE_LINK
|
||||
|
||||
def column_order(self):
|
||||
"""
|
||||
returns a tuple indicating the column order
|
||||
"""
|
||||
return self.dbstate.db.get_note_column_order()
|
||||
|
||||
def get_stock(self):
|
||||
"""
|
||||
Use the gramps-event stock icon
|
||||
"""
|
||||
return 'gramps-notes'
|
||||
|
||||
def ui_definition(self):
|
||||
"""
|
||||
Defines the UI string for UIManager
|
||||
"""
|
||||
return '''<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu action="FileMenu">
|
||||
<placeholder name="LocalExport">
|
||||
<menuitem action="ExportTab"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="BookMenu">
|
||||
<placeholder name="AddEditBook">
|
||||
<menuitem action="AddBook"/>
|
||||
<menuitem action="EditBook"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="EditMenu">
|
||||
<placeholder name="CommonEdit">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<menuitem action="FilterEdit"/>
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
<toolitem action="Remove"/>
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def define_actions(self):
|
||||
ListView.define_actions(self)
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor'), callback=self._column_editor)
|
||||
self._add_action('FilterEdit', None, _('Note Filter Editor'),
|
||||
callback=self.filter_editor,)
|
||||
|
||||
def get_handle_from_gramps_id(self, gid):
|
||||
obj = self.dbstate.db.get_note_from_gramps_id(gid)
|
||||
if obj:
|
||||
return obj.get_handle()
|
||||
else:
|
||||
return None
|
||||
|
||||
def _column_editor(self, obj):
|
||||
"""
|
||||
returns a tuple indicating the column order
|
||||
"""
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Note Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_note_column_order(),
|
||||
NoteView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def add(self, obj):
|
||||
try:
|
||||
EditNote(self.dbstate, self.uistate, [], Note())
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def remove(self, obj):
|
||||
self.remove_selected_objects()
|
||||
|
||||
def remove_object_from_handle(self, handle):
|
||||
the_lists = Utils.get_note_referents(handle, self.dbstate.db)
|
||||
object = self.dbstate.db.get_note_from_handle(handle)
|
||||
query = DeleteNoteQuery(self.dbstate, self.uistate, object, the_lists)
|
||||
is_used = any(the_lists)
|
||||
return (query, is_used, object)
|
||||
|
||||
def edit(self, obj):
|
||||
for handle in self.selected_handles():
|
||||
note = self.dbstate.db.get_note_from_handle(handle)
|
||||
try:
|
||||
EditNote(self.dbstate, self.uistate, [], note)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
1823
src/plugins/view/pedigreeview.py
Normal file
1823
src/plugins/view/pedigreeview.py
Normal file
File diff suppressed because it is too large
Load Diff
464
src/plugins/view/personview.py
Normal file
464
src/plugins/view/personview.py
Normal file
@@ -0,0 +1,464 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# Copyright (C) 2008 Gary Burton
|
||||
# Copyright (C) 2009 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$
|
||||
|
||||
"""
|
||||
Provide the person view.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# set up logging
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import logging
|
||||
_LOG = logging.getLogger(".gui.personview")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
from gui.views.pageview import NAVIGATION_PERSON
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import PeopleModel
|
||||
import Utils
|
||||
from BasicUtils import name_displayer
|
||||
from QuestionDialog import ErrorDialog, QuestionDialog
|
||||
import Errors
|
||||
import Bookmarks
|
||||
import config
|
||||
from DdTargets import DdTargets
|
||||
from Editors import EditPerson
|
||||
from Filters.SideBar import PersonSidebarFilter
|
||||
from gen.plug import CATEGORY_QR_PERSON
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from TransUtils import sgettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# PersonView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class PersonView(ListView):
|
||||
"""
|
||||
PersonView class, derived from the ListView
|
||||
"""
|
||||
COLUMN_NAMES = [
|
||||
_('Name'),
|
||||
_('ID'),
|
||||
_('Gender'),
|
||||
_('Birth Date'),
|
||||
_('Birth Place'),
|
||||
_('Death Date'),
|
||||
_('Death Place'),
|
||||
_('Spouse'),
|
||||
_('Last Changed'),
|
||||
]
|
||||
|
||||
ADD_MSG = _("Add a new person")
|
||||
EDIT_MSG = _("Edit the selected person")
|
||||
DEL_MSG = _("Delete the selected person")
|
||||
FILTER_TYPE = "Person"
|
||||
QR_CATEGORY = CATEGORY_QR_PERSON
|
||||
|
||||
def __init__(self, dbstate, uistate):
|
||||
"""
|
||||
Create the Person View
|
||||
"""
|
||||
signal_map = {
|
||||
'person-add' : self.row_add,
|
||||
'person-update' : self.row_update,
|
||||
'person-delete' : self.row_delete,
|
||||
'person-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
self, _('People'), dbstate, uistate,
|
||||
PersonView.COLUMN_NAMES, len(PersonView.COLUMN_NAMES),
|
||||
PeopleModel,
|
||||
signal_map, dbstate.db.get_bookmarks(),
|
||||
Bookmarks.Bookmarks,
|
||||
multiple=True,
|
||||
filter_class=PersonSidebarFilter,
|
||||
markup=True)
|
||||
|
||||
self.func_list = {
|
||||
'<CONTROL>J' : self.jump,
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
config.connect("interface.filter", self.filter_toggle)
|
||||
|
||||
def column_ord_setfunc(self, clist):
|
||||
self.dbstate.db.set_person_column_order(clist)
|
||||
|
||||
def navigation_type(self):
|
||||
return NAVIGATION_PERSON
|
||||
|
||||
def get_bookmarks(self):
|
||||
"""
|
||||
Return the bookmark object
|
||||
"""
|
||||
return self.dbstate.db.get_bookmarks()
|
||||
|
||||
def drag_info(self):
|
||||
"""
|
||||
Specify the drag type for a single selection
|
||||
"""
|
||||
return DdTargets.PERSON_LINK
|
||||
|
||||
def drag_list_info(self):
|
||||
"""
|
||||
Specify the drag type for a multiple selected rows
|
||||
"""
|
||||
return DdTargets.PERSON_LINK_LIST
|
||||
|
||||
def column_order(self):
|
||||
"""
|
||||
returns a tuple indicating the column order
|
||||
"""
|
||||
return self.dbstate.db.get_person_column_order()
|
||||
|
||||
def exact_search(self):
|
||||
"""
|
||||
Returns a tuple indicating columns requiring an exact search
|
||||
"""
|
||||
return (2,) # Gender ('female' contains the string 'male')
|
||||
|
||||
def get_stock(self):
|
||||
"""
|
||||
Use the gramps-person stock icon
|
||||
"""
|
||||
return 'gramps-person'
|
||||
|
||||
def ui_definition(self):
|
||||
"""
|
||||
Defines the UI string for UIManager
|
||||
"""
|
||||
return '''<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu action="FileMenu">
|
||||
<placeholder name="LocalExport">
|
||||
<menuitem action="ExportTab"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="BookMenu">
|
||||
<placeholder name="AddEditBook">
|
||||
<menuitem action="AddBook"/>
|
||||
<menuitem action="EditBook"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="GoMenu">
|
||||
<placeholder name="CommonGo">
|
||||
<menuitem action="Back"/>
|
||||
<menuitem action="Forward"/>
|
||||
<separator/>
|
||||
<menuitem action="HomePerson"/>
|
||||
<separator/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="EditMenu">
|
||||
<placeholder name="CommonEdit">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</placeholder>
|
||||
<menuitem action="SetActive"/>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<menuitem action="FilterEdit"/>
|
||||
<placeholder name="Merge">
|
||||
<menuitem action="CmpMerge"/>
|
||||
<menuitem action="FastMerge"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonNavigation">
|
||||
<toolitem action="Back"/>
|
||||
<toolitem action="Forward"/>
|
||||
<toolitem action="HomePerson"/>
|
||||
</placeholder>
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
<toolitem action="Remove"/>
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Back"/>
|
||||
<menuitem action="Forward"/>
|
||||
<menuitem action="HomePerson"/>
|
||||
<separator/>
|
||||
<menuitem action="OpenAllNodes"/>
|
||||
<menuitem action="CloseAllNodes"/>
|
||||
<separator/>
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
<separator/>
|
||||
<menu name="QuickReport" action="QuickReport">
|
||||
<menuitem action="Dummy"/>
|
||||
</menu>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def get_handle_from_gramps_id(self, gid):
|
||||
obj = self.dbstate.db.get_person_from_gramps_id(gid)
|
||||
if obj:
|
||||
return obj.get_handle()
|
||||
else:
|
||||
return None
|
||||
|
||||
def _column_editor(self, obj):
|
||||
"""
|
||||
returns a tuple indicating the column order
|
||||
"""
|
||||
import ColumnOrder
|
||||
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Person Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_person_column_order(),
|
||||
PersonView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def add(self, obj):
|
||||
person = gen.lib.Person()
|
||||
|
||||
# attempt to get the current surname
|
||||
(model, pathlist) = self.selection.get_selected_rows()
|
||||
name = u""
|
||||
if len(pathlist) == 1:
|
||||
path = pathlist[0]
|
||||
if len(path) == 1:
|
||||
name = model.on_get_iter(path)
|
||||
else:
|
||||
node = model.on_get_iter(path)
|
||||
name = model.on_iter_parent(node)
|
||||
|
||||
try:
|
||||
person.get_primary_name().set_surname(name)
|
||||
EditPerson(self.dbstate, self.uistate, [], person)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def edit(self, obj):
|
||||
for handle in self.selected_handles():
|
||||
person = self.dbstate.db.get_person_from_handle(handle)
|
||||
try:
|
||||
EditPerson(self.dbstate, self.uistate, [], person)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def remove(self, obj):
|
||||
for sel in self.selected_handles():
|
||||
person = self.dbstate.db.get_person_from_handle(sel)
|
||||
self.active_person = person
|
||||
name = name_displayer.display(person)
|
||||
|
||||
msg = _('Deleting the person will remove the person '
|
||||
'from the database.')
|
||||
msg = "%s %s" % (msg, Utils.data_recover_msg)
|
||||
QuestionDialog(_('Delete %s?') % name,
|
||||
msg,
|
||||
_('_Delete Person'),
|
||||
self.delete_person_response)
|
||||
|
||||
def delete_person_response(self):
|
||||
"""
|
||||
Deletes the person from the database.
|
||||
"""
|
||||
# set the busy cursor, so the user knows that we are working
|
||||
self.uistate.set_busy_cursor(True)
|
||||
|
||||
# create the transaction
|
||||
trans = self.dbstate.db.transaction_begin()
|
||||
|
||||
# create name to save
|
||||
person = self.active_person
|
||||
active_name = _("Delete Person (%s)") % name_displayer.display(person)
|
||||
|
||||
# delete the person from the database
|
||||
gen.utils.delete_person_from_database(self.dbstate.db, person, trans)
|
||||
|
||||
# remove the person from the list
|
||||
self.remove_from_person_list(person)
|
||||
|
||||
# commit the transaction
|
||||
self.dbstate.db.transaction_commit(trans, active_name)
|
||||
|
||||
# select the previously active person, turn off the busy cursor
|
||||
self.uistate.phistory.back()
|
||||
self.uistate.set_busy_cursor(False)
|
||||
|
||||
def remove_from_person_list(self, person):
|
||||
"""Remove the selected person from the list. A person object is
|
||||
expected, not an ID"""
|
||||
path = self.model.on_get_path(person.get_handle())
|
||||
(col, row) = path
|
||||
if row > 0:
|
||||
self.selection.select_path((col, row-1))
|
||||
elif row == 0 and self.model.on_get_iter(path):
|
||||
self.selection.select_path(path)
|
||||
|
||||
def dummy_report(self, obj):
|
||||
""" For the xml UI definition of popup to work, the submenu
|
||||
Quick Report must have an entry in the xml
|
||||
As this submenu will be dynamically built, we offer a dummy action
|
||||
"""
|
||||
pass
|
||||
|
||||
def define_actions(self):
|
||||
"""
|
||||
Required define_actions function for PageView. Builds the action
|
||||
group information required. We extend beyond the normal here,
|
||||
since we want to have more than one action group for the PersonView.
|
||||
Most PageViews really won't care about this.
|
||||
|
||||
Special action groups for Forward and Back are created to allow the
|
||||
handling of navigation buttons. Forward and Back allow the user to
|
||||
advance or retreat throughout the history, and we want to have these
|
||||
be able to toggle these when you are at the end of the history or
|
||||
at the beginning of the history.
|
||||
"""
|
||||
|
||||
ListView.define_actions(self)
|
||||
|
||||
self.all_action = gtk.ActionGroup(self.title + "/PersonAll")
|
||||
self.edit_action = gtk.ActionGroup(self.title + "/PersonEdit")
|
||||
|
||||
self.all_action.add_actions([
|
||||
('FilterEdit', None, _('Person Filter Editor'), None, None,
|
||||
self.filter_editor),
|
||||
('OpenAllNodes', None, _("Expand all Nodes"), None, None,
|
||||
self.open_all_nodes),
|
||||
('Edit', gtk.STOCK_EDIT, _("action|_Edit..."), "<control>Return",
|
||||
_("Edit the selected person"), self.edit),
|
||||
('CloseAllNodes', None, _("Collapse all Nodes"), None, None,
|
||||
self.close_all_nodes),
|
||||
('QuickReport', None, _("Quick View"), None, None, None),
|
||||
('Dummy', None, ' ', None, None, self.dummy_report),
|
||||
])
|
||||
|
||||
self.edit_action.add_actions(
|
||||
[
|
||||
('Add', gtk.STOCK_ADD, _("_Add..."), "<control>Insert",
|
||||
_("Add a new person"), self.add),
|
||||
('Remove', gtk.STOCK_REMOVE, _("_Remove"), "<control>Delete",
|
||||
_("Remove the Selected Person"), self.remove),
|
||||
('ColumnEdit', gtk.STOCK_PROPERTIES, _('_Column Editor...'), None,
|
||||
None, self._column_editor),
|
||||
('CmpMerge', None, _('Compare and _Merge...'), None, None,
|
||||
self.cmp_merge),
|
||||
('FastMerge', None, _('_Fast Merge...'), None, None,
|
||||
self.fast_merge),
|
||||
('ExportTab', None, _('Export View...'), None, None, self.export),
|
||||
])
|
||||
|
||||
self._add_action_group(self.edit_action)
|
||||
self._add_action_group(self.all_action)
|
||||
|
||||
def enable_action_group(self, obj):
|
||||
ListView.enable_action_group(self, obj)
|
||||
self.all_action.set_visible(True)
|
||||
self.edit_action.set_visible(False)
|
||||
self.edit_action.set_sensitive(not self.dbstate.db.readonly)
|
||||
|
||||
def disable_action_group(self):
|
||||
ListView.disable_action_group(self)
|
||||
|
||||
self.all_action.set_visible(False)
|
||||
self.edit_action.set_visible(False)
|
||||
|
||||
def open_all_nodes(self, obj):
|
||||
self.uistate.status_text(_("Updating display..."))
|
||||
self.uistate.set_busy_cursor(True)
|
||||
|
||||
self.list.expand_all()
|
||||
|
||||
self.uistate.set_busy_cursor(False)
|
||||
self.uistate.modify_statusbar(self.dbstate)
|
||||
|
||||
def close_all_nodes(self, obj):
|
||||
self.list.collapse_all()
|
||||
|
||||
def cmp_merge(self, obj):
|
||||
mlist = self.get_selected_objects()
|
||||
|
||||
if len(mlist) != 2:
|
||||
ErrorDialog(
|
||||
_("Cannot merge people"),
|
||||
_("Exactly two people must be selected to perform a merge. "
|
||||
"A second person can be selected by holding down the "
|
||||
"control key while clicking on the desired person."))
|
||||
else:
|
||||
import Merge
|
||||
person1 = self.db.get_person_from_handle(mlist[0])
|
||||
person2 = self.db.get_person_from_handle(mlist[1])
|
||||
if person1 and person2:
|
||||
Merge.PersonCompare(self.dbstate, self.uistate, person1,
|
||||
person2, self.build_tree)
|
||||
else:
|
||||
ErrorDialog(
|
||||
_("Cannot merge people"),
|
||||
_("Exactly two people must be selected to perform a "
|
||||
"merge. A second person can be selected by holding "
|
||||
"down the control key while clicking on the desired "
|
||||
"person."))
|
||||
|
||||
def fast_merge(self, obj):
|
||||
mlist = self.get_selected_objects()
|
||||
|
||||
if len(mlist) != 2:
|
||||
ErrorDialog(
|
||||
_("Cannot merge people"),
|
||||
_("Exactly two people must be selected to perform a merge. "
|
||||
"A second person can be selected by holding down the "
|
||||
"control key while clicking on the desired person."))
|
||||
else:
|
||||
import Merge
|
||||
|
||||
person1 = self.db.get_person_from_handle(mlist[0])
|
||||
person2 = self.db.get_person_from_handle(mlist[1])
|
||||
if person1 and person2:
|
||||
Merge.MergePeopleUI(self.dbstate, self.uistate, person1,
|
||||
person2, self.build_tree)
|
||||
else:
|
||||
ErrorDialog(
|
||||
_("Cannot merge people"),
|
||||
_("Exactly two people must be selected to perform a merge. "
|
||||
"A second person can be selected by holding down the "
|
||||
"control key while clicking on the desired person."))
|
382
src/plugins/view/placeview.py
Normal file
382
src/plugins/view/placeview.py
Normal file
@@ -0,0 +1,382 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-2006 Donald N. Allingham
|
||||
# Copyright (C) 2008 Gary Burton
|
||||
#
|
||||
# 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$
|
||||
|
||||
"""
|
||||
Place View
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Global modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import PlaceModel
|
||||
from gui.utils import add_menuitem
|
||||
import Errors
|
||||
import Bookmarks
|
||||
import config
|
||||
from QuestionDialog import ErrorDialog
|
||||
from gui.pluginmanager import GuiPluginManager
|
||||
from DdTargets import DdTargets
|
||||
from Editors import EditPlace, DeletePlaceQuery
|
||||
from Filters.SideBar import PlaceSidebarFilter
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# PlaceView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class PlaceView(ListView):
|
||||
|
||||
COLUMN_NAMES = [
|
||||
_('Place Name'),
|
||||
_('ID'),
|
||||
_('Church Parish'),
|
||||
_('ZIP/Postal Code'),
|
||||
_('City'),
|
||||
_('County'),
|
||||
_('State'),
|
||||
_('Country'),
|
||||
_('Latitude'),
|
||||
_('Longitude'),
|
||||
_('Last Changed'),
|
||||
_('Street'),
|
||||
]
|
||||
|
||||
ADD_MSG = _("Add a new place")
|
||||
EDIT_MSG = _("Edit the selected place")
|
||||
DEL_MSG = _("Delete the selected place")
|
||||
FILTER_TYPE = "Place"
|
||||
|
||||
def __init__(self, dbstate, uistate):
|
||||
|
||||
signal_map = {
|
||||
'place-add' : self.row_add,
|
||||
'place-update' : self.row_update,
|
||||
'place-delete' : self.row_delete,
|
||||
'place-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
self.func_list = {
|
||||
'<CONTROL>J' : self.jump,
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
self.mapservice = config.get('interface.mapservice')
|
||||
self.mapservicedata = {}
|
||||
|
||||
ListView.__init__(
|
||||
self, _('Places'), dbstate, uistate, PlaceView.COLUMN_NAMES,
|
||||
len(PlaceView.COLUMN_NAMES),
|
||||
PlaceModel, signal_map,
|
||||
dbstate.db.get_place_bookmarks(),
|
||||
Bookmarks.PlaceBookmarks,
|
||||
multiple=True,
|
||||
filter_class=PlaceSidebarFilter)
|
||||
|
||||
config.connect("interface.filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def column_ord_setfunc(self, clist):
|
||||
self.dbstate.db.set_place_column_order(clist)
|
||||
|
||||
def get_bookmarks(self):
|
||||
return self.dbstate.db.get_place_bookmarks()
|
||||
|
||||
def define_actions(self):
|
||||
ListView.define_actions(self)
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor'), callback=self._column_editor)
|
||||
self._add_action('FastMerge', None, _('_Merge...'),
|
||||
callback=self.fast_merge)
|
||||
self._add_toolmenu_action('MapsList', _('Loading...'),
|
||||
_("Attempt to see selected locations with a Map "
|
||||
"Service (OpenstreetMap, Google Maps, ...)"),
|
||||
self.gotomap,
|
||||
_('Select a Map Service'))
|
||||
self._add_action('GotoMap', gtk.STOCK_JUMP_TO,
|
||||
_('_Look up with Map Service'),
|
||||
callback=self.gotomap,
|
||||
tip=_("Attempt to see this location with a Map "
|
||||
"Service (OpenstreetMap, Google Maps, ...)"))
|
||||
self._add_action('FilterEdit', None, _('Place Filter Editor'),
|
||||
callback=self.filter_editor)
|
||||
|
||||
def change_page(self):
|
||||
"""
|
||||
Called by viewmanager at end of realization when arriving on the page
|
||||
At this point the Toolbar is created. We need to:
|
||||
1. get the menutoolbutton
|
||||
2. add all possible map services in the drop down menu
|
||||
3. add the actions that correspond to clicking in this drop down menu
|
||||
4. set icon and label of the menutoolbutton now that it is realized
|
||||
5. store label so it can be changed when selection changes
|
||||
"""
|
||||
ListView.change_page(self)
|
||||
#menutoolbutton actions are stored in PageView class,
|
||||
# obtain the widgets where we need to add to menu
|
||||
actionservices = self.action_toolmenu['MapsList']
|
||||
widgets = actionservices.get_proxies()
|
||||
mmenu = self.__create_maps_menu_actions()
|
||||
|
||||
if not self.mapservicedata:
|
||||
return
|
||||
|
||||
self.mapslistlabel = []
|
||||
if not self.mapservice in self.mapservicedata:
|
||||
#stored val no longer exists, use the first key instead
|
||||
self.set_mapservice(self.mapservicedata.keys()[0])
|
||||
|
||||
#store all gtk labels to be able to update label on selection change
|
||||
for widget in widgets :
|
||||
if isinstance(widget, gtk.MenuToolButton):
|
||||
widget.set_menu(mmenu)
|
||||
if gtk.pygtk_version >= (2, 12, 0):
|
||||
widget.set_arrow_tooltip_text(actionservices.arrowtooltip)
|
||||
lbl = gtk.Label(self.mapservice_label())
|
||||
lbl.show()
|
||||
self.mapslistlabel.append(lbl)
|
||||
widget.set_label_widget(self.mapslistlabel[-1])
|
||||
widget.set_stock_id(gtk.STOCK_JUMP_TO)
|
||||
if self.drag_info():
|
||||
self.list.enable_model_drag_source(gtk.gdk.BUTTON1_MASK,
|
||||
[('text/plain', 0, 0), self.drag_info().target()],
|
||||
gtk.gdk.ACTION_COPY)
|
||||
|
||||
def __create_maps_menu_actions(self):
|
||||
"""
|
||||
Function creating a menu and actions that are used as dropdown menu
|
||||
from the menutoolbutton
|
||||
"""
|
||||
menu = gtk.Menu()
|
||||
|
||||
#select the map services to show
|
||||
self.mapservicedata = {}
|
||||
servlist = GuiPluginManager.get_instance().get_reg_mapservices()
|
||||
for i, pdata in zip(range(len(servlist)), servlist):
|
||||
key = pdata.id.replace(' ', '-')
|
||||
add_menuitem(menu, pdata.name, None,
|
||||
make_callback(self.set_mapservice, key))
|
||||
self.mapservicedata[key] = pdata
|
||||
|
||||
return menu
|
||||
|
||||
def set_mapservice(self, mapkey):
|
||||
"""
|
||||
change the service that runs on click of the menutoolbutton
|
||||
used as callback menu on menu clicks
|
||||
"""
|
||||
self.mapservice = mapkey
|
||||
for label in self.mapslistlabel:
|
||||
label.set_label(self.mapservice_label())
|
||||
label.show()
|
||||
config.set('interface.mapservice', mapkey)
|
||||
config.save()
|
||||
|
||||
def mapservice_label(self):
|
||||
"""
|
||||
return the current label for the menutoolbutton
|
||||
"""
|
||||
return self.mapservicedata[self.mapservice].name
|
||||
|
||||
def gotomap(self, obj):
|
||||
"""
|
||||
Run the map service
|
||||
"""
|
||||
#First test if any map service is available
|
||||
if not len(self.mapservicedata):
|
||||
msg = _("No map service is available.")
|
||||
msg2 = _("Check your installation.")
|
||||
ErrorDialog(msg, msg2)
|
||||
return
|
||||
|
||||
place_handles = self.selected_handles()
|
||||
try:
|
||||
place_handle = self.selected_handles()[0]
|
||||
except IndexError:
|
||||
msg = _("No place selected.")
|
||||
msg2 = _("You need to select a place to be able to view it"
|
||||
" on a map. Some Map Services might support multiple"
|
||||
" selections.")
|
||||
ErrorDialog(msg, msg2)
|
||||
return
|
||||
|
||||
#TODO: support for descriptions in some cases. For now, pass None
|
||||
#TODO: Later this might be 'Birth of William' ....
|
||||
places = [(x, None) for x in place_handles]
|
||||
|
||||
#run the mapservice:
|
||||
pmgr = GuiPluginManager.get_instance()
|
||||
serv = self.mapservicedata[self.mapservice]
|
||||
mod = pmgr.load_plugin(serv)
|
||||
if mod:
|
||||
servfunc = eval('mod.' + serv.mapservice)
|
||||
servfunc()(self.dbstate.db, places)
|
||||
else:
|
||||
print 'Failed to load map plugin, see Plugin Status'
|
||||
|
||||
def drag_info(self):
|
||||
return DdTargets.PLACE_LINK
|
||||
|
||||
def _column_editor(self, obj):
|
||||
import ColumnOrder
|
||||
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Place Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_place_column_order(),
|
||||
PlaceView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def column_order(self):
|
||||
return self.dbstate.db.get_place_column_order()
|
||||
|
||||
def get_stock(self):
|
||||
return 'gramps-place'
|
||||
|
||||
def ui_definition(self):
|
||||
return '''<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu action="FileMenu">
|
||||
<placeholder name="LocalExport">
|
||||
<menuitem action="ExportTab"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="BookMenu">
|
||||
<placeholder name="AddEditBook">
|
||||
<menuitem action="AddBook"/>
|
||||
<menuitem action="EditBook"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="EditMenu">
|
||||
<placeholder name="CommonEdit">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<menuitem action="FilterEdit"/>
|
||||
<placeholder name="Merge">
|
||||
<menuitem action="FastMerge"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
<toolitem action="Remove"/>
|
||||
<separator/>
|
||||
<toolitem action="MapsList"/>
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
<menuitem action="GotoMap"/>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def add(self, obj):
|
||||
try:
|
||||
EditPlace(self.dbstate, self.uistate, [], gen.lib.Place())
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def remove(self, obj):
|
||||
self.remove_selected_objects()
|
||||
|
||||
def remove_object_from_handle(self, handle):
|
||||
person_list = [
|
||||
item[1] for item in
|
||||
self.dbstate.db.find_backlink_handles(handle,['Person'])]
|
||||
|
||||
family_list = [
|
||||
item[1] for item in
|
||||
self.dbstate.db.find_backlink_handles(handle,['Family'])]
|
||||
|
||||
event_list = [
|
||||
item[1] for item in
|
||||
self.dbstate.db.find_backlink_handles(handle,['Event'])]
|
||||
|
||||
object = self.dbstate.db.get_place_from_handle(handle)
|
||||
query = DeletePlaceQuery(self.dbstate, self.uistate, object,
|
||||
person_list, family_list, event_list)
|
||||
|
||||
is_used = len(person_list) + len(family_list) + len(event_list) > 0
|
||||
return (query, is_used, object)
|
||||
|
||||
def edit(self, obj):
|
||||
for handle in self.selected_handles():
|
||||
place = self.dbstate.db.get_place_from_handle(handle)
|
||||
try:
|
||||
EditPlace(self.dbstate, self.uistate, [], place)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def fast_merge(self, obj):
|
||||
mlist = self.selected_handles()
|
||||
|
||||
if len(mlist) != 2:
|
||||
msg = _("Cannot merge places.")
|
||||
msg2 = _("Exactly two places must be selected to perform a merge. "
|
||||
"A second place can be selected by holding down the "
|
||||
"control key while clicking on the desired place.")
|
||||
ErrorDialog(msg, msg2)
|
||||
else:
|
||||
import Merge
|
||||
Merge.MergePlaces(self.dbstate, self.uistate, mlist[0], mlist[1])
|
||||
|
||||
def get_handle_from_gramps_id(self, gid):
|
||||
obj = self.dbstate.db.get_place_from_gramps_id(gid)
|
||||
if obj:
|
||||
return obj.get_handle()
|
||||
else:
|
||||
return None
|
||||
|
||||
def make_callback(func, val):
|
||||
return lambda x: func(val)
|
1622
src/plugins/view/relview.py
Normal file
1622
src/plugins/view/relview.py
Normal file
File diff suppressed because it is too large
Load Diff
227
src/plugins/view/repoview.py
Normal file
227
src/plugins/view/repoview.py
Normal file
@@ -0,0 +1,227 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-2006 Donald N. Allingham
|
||||
# Copyright (C) 2008 Gary Burton
|
||||
#
|
||||
# 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$
|
||||
|
||||
"""
|
||||
Repository View
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import RepositoryModel
|
||||
import Utils
|
||||
import Bookmarks
|
||||
import Errors
|
||||
import config
|
||||
from Editors import EditRepository, DelRepositoryQuery
|
||||
from DdTargets import DdTargets
|
||||
from Filters.SideBar import RepoSidebarFilter
|
||||
from gen.plug import CATEGORY_QR_REPOSITORY
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# RepositoryView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class RepositoryView(ListView):
|
||||
|
||||
COLUMN_NAMES = [
|
||||
_('Name'),
|
||||
_('ID'),
|
||||
_('Type'),
|
||||
_('Home URL'),
|
||||
_('Street'),
|
||||
_('ZIP/Postal Code'),
|
||||
_('City'),
|
||||
_('County'),
|
||||
_('State'),
|
||||
_('Country'),
|
||||
_('Email'),
|
||||
_('Search URL'),
|
||||
_('Last Changed'),
|
||||
]
|
||||
|
||||
ADD_MSG = _("Add a new repository")
|
||||
EDIT_MSG = _("Edit the selected repository")
|
||||
DEL_MSG = _("Delete the selected repository")
|
||||
FILTER_TYPE = "Repository"
|
||||
QR_CATEGORY = CATEGORY_QR_REPOSITORY
|
||||
|
||||
def __init__(self, dbstate, uistate):
|
||||
|
||||
signal_map = {
|
||||
'repository-add' : self.row_add,
|
||||
'repository-update' : self.row_update,
|
||||
'repository-delete' : self.row_delete,
|
||||
'repository-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
self.func_list = {
|
||||
'<CONTROL>J' : self.jump,
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
self, _('Repositories'), dbstate, uistate,
|
||||
RepositoryView.COLUMN_NAMES, len(RepositoryView.COLUMN_NAMES),
|
||||
RepositoryModel, signal_map,
|
||||
dbstate.db.get_repo_bookmarks(),
|
||||
Bookmarks.RepoBookmarks, multiple=True,
|
||||
filter_class=RepoSidebarFilter)
|
||||
|
||||
config.connect("interface.filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def column_ord_setfunc(self, clist):
|
||||
self.dbstate.db.set_repository_column_order(clist)
|
||||
|
||||
def get_bookmarks(self):
|
||||
return self.dbstate.db.get_repo_bookmarks()
|
||||
|
||||
def drag_info(self):
|
||||
return DdTargets.REPO_LINK
|
||||
|
||||
def define_actions(self):
|
||||
ListView.define_actions(self)
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor'), callback=self._column_editor)
|
||||
self._add_action('FilterEdit', None, _('Repository Filter Editor'),
|
||||
callback=self.filter_editor,)
|
||||
self._add_action('QuickReport', None,
|
||||
_("Quick View"), None, None, None)
|
||||
self._add_action('Dummy', None,
|
||||
' ', None, None, self.dummy_report)
|
||||
|
||||
def _column_editor(self, obj):
|
||||
import ColumnOrder
|
||||
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Repository Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_repository_column_order(),
|
||||
RepositoryView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def column_order(self):
|
||||
return self.dbstate.db.get_repository_column_order()
|
||||
|
||||
def get_stock(self):
|
||||
return 'gramps-repository'
|
||||
|
||||
def ui_definition(self):
|
||||
return '''<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu action="FileMenu">
|
||||
<placeholder name="LocalExport">
|
||||
<menuitem action="ExportTab"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="BookMenu">
|
||||
<placeholder name="AddEditBook">
|
||||
<menuitem action="AddBook"/>
|
||||
<menuitem action="EditBook"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="EditMenu">
|
||||
<placeholder name="CommonEdit">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<menuitem action="FilterEdit"/>
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
<toolitem action="Remove"/>
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
<separator/>
|
||||
<menu name="QuickReport" action="QuickReport">
|
||||
<menuitem action="Dummy"/>
|
||||
</menu>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def add(self, obj):
|
||||
EditRepository(self.dbstate, self.uistate, [], gen.lib.Repository())
|
||||
|
||||
def remove(self, obj):
|
||||
self.remove_selected_objects()
|
||||
|
||||
def remove_object_from_handle(self, handle):
|
||||
source_list = [
|
||||
item[1] for item in
|
||||
self.dbstate.db.find_backlink_handles(handle, ['Source'])]
|
||||
object = self.dbstate.db.get_repository_from_handle(handle)
|
||||
query = DelRepositoryQuery(self.dbstate, self.uistate, object,
|
||||
source_list)
|
||||
is_used = len(source_list) > 0
|
||||
return (query, is_used, object)
|
||||
|
||||
def edit(self, obj):
|
||||
for handle in self.selected_handles():
|
||||
repos = self.dbstate.db.get_repository_from_handle(handle)
|
||||
try:
|
||||
EditRepository(self.dbstate, self.uistate, [], repos)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def get_handle_from_gramps_id(self, gid):
|
||||
obj = self.dbstate.db.get_repository_from_gramps_id(gid)
|
||||
if obj:
|
||||
return obj.get_handle()
|
||||
else:
|
||||
return None
|
||||
|
||||
def dummy_report(self, obj):
|
||||
""" For the xml UI definition of popup to work, the submenu
|
||||
Quick Report must have an entry in the xml
|
||||
As this submenu will be dynamically built, we offer a dummy action
|
||||
"""
|
||||
pass
|
219
src/plugins/view/sourceview.py
Normal file
219
src/plugins/view/sourceview.py
Normal file
@@ -0,0 +1,219 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2001-2006 Donald N. Allingham
|
||||
# Copyright (C) 2008 Gary Burton
|
||||
#
|
||||
# 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$
|
||||
|
||||
"""
|
||||
Source View
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
import config
|
||||
from gui.views.listview import ListView
|
||||
from gui.views.treemodels import SourceModel
|
||||
import Utils
|
||||
import Bookmarks
|
||||
import Errors
|
||||
from DdTargets import DdTargets
|
||||
from QuestionDialog import ErrorDialog
|
||||
from Editors import EditSource, DelSrcQuery
|
||||
from Filters.SideBar import SourceSidebarFilter
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# SourceView
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class SourceView(ListView):
|
||||
|
||||
COLUMN_NAMES = [
|
||||
_('Title'),
|
||||
_('ID'),
|
||||
_('Author'),
|
||||
_('Abbreviation'),
|
||||
_('Publication Information'),
|
||||
_('Last Changed'),
|
||||
]
|
||||
|
||||
ADD_MSG = _("Add a new source")
|
||||
EDIT_MSG = _("Edit the selected source")
|
||||
DEL_MSG = _("Delete the selected source")
|
||||
FILTER_TYPE = "Source"
|
||||
|
||||
def __init__(self, dbstate, uistate):
|
||||
|
||||
signal_map = {
|
||||
'source-add' : self.row_add,
|
||||
'source-update' : self.row_update,
|
||||
'source-delete' : self.row_delete,
|
||||
'source-rebuild' : self.object_build,
|
||||
}
|
||||
|
||||
self.func_list = {
|
||||
'<CONTROL>J' : self.jump,
|
||||
'<CONTROL>BackSpace' : self.key_delete,
|
||||
}
|
||||
|
||||
ListView.__init__(
|
||||
self, _('Sources'), dbstate, uistate,
|
||||
SourceView.COLUMN_NAMES, len(SourceView.COLUMN_NAMES),
|
||||
SourceModel, signal_map,
|
||||
dbstate.db.get_source_bookmarks(),
|
||||
Bookmarks.SourceBookmarks, multiple=True,
|
||||
filter_class=SourceSidebarFilter)
|
||||
|
||||
config.connect("interface.filter",
|
||||
self.filter_toggle)
|
||||
|
||||
def column_ord_setfunc(self, clist):
|
||||
self.dbstate.db.set_source_column_order(clist)
|
||||
|
||||
def get_bookmarks(self):
|
||||
return self.dbstate.db.get_source_bookmarks()
|
||||
|
||||
def drag_info(self):
|
||||
return DdTargets.SOURCE_LINK
|
||||
|
||||
def define_actions(self):
|
||||
ListView.define_actions(self)
|
||||
self._add_action('ColumnEdit', gtk.STOCK_PROPERTIES,
|
||||
_('_Column Editor'), callback=self._column_editor)
|
||||
self._add_action('FastMerge', None, _('_Merge'),
|
||||
callback=self.fast_merge)
|
||||
self._add_action('FilterEdit', None, _('Source Filter Editor'),
|
||||
callback=self.filter_editor,)
|
||||
|
||||
def _column_editor(self, obj):
|
||||
import ColumnOrder
|
||||
|
||||
ColumnOrder.ColumnOrder(
|
||||
_('Select Source Columns'),
|
||||
self.uistate,
|
||||
self.dbstate.db.get_source_column_order(),
|
||||
SourceView.COLUMN_NAMES,
|
||||
self.set_column_order)
|
||||
|
||||
def column_order(self):
|
||||
return self.dbstate.db.get_source_column_order()
|
||||
|
||||
def get_stock(self):
|
||||
return 'gramps-source'
|
||||
|
||||
def ui_definition(self):
|
||||
return '''<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu action="FileMenu">
|
||||
<placeholder name="LocalExport">
|
||||
<menuitem action="ExportTab"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="BookMenu">
|
||||
<placeholder name="AddEditBook">
|
||||
<menuitem action="AddBook"/>
|
||||
<menuitem action="EditBook"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
<menu action="EditMenu">
|
||||
<placeholder name="CommonEdit">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</placeholder>
|
||||
<menuitem action="ColumnEdit"/>
|
||||
<menuitem action="FilterEdit"/>
|
||||
<placeholder name="Merge">
|
||||
<menuitem action="FastMerge"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
</menubar>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="CommonEdit">
|
||||
<toolitem action="Add"/>
|
||||
<toolitem action="Edit"/>
|
||||
<toolitem action="Remove"/>
|
||||
</placeholder>
|
||||
</toolbar>
|
||||
<popup name="Popup">
|
||||
<menuitem action="Add"/>
|
||||
<menuitem action="Edit"/>
|
||||
<menuitem action="Remove"/>
|
||||
</popup>
|
||||
</ui>'''
|
||||
|
||||
def add(self, obj):
|
||||
EditSource(self.dbstate, self.uistate, [], gen.lib.Source())
|
||||
|
||||
def remove(self, obj):
|
||||
self.remove_selected_objects()
|
||||
|
||||
def remove_object_from_handle(self, handle):
|
||||
the_lists = Utils.get_source_referents(handle, self.dbstate.db)
|
||||
object = self.dbstate.db.get_source_from_handle(handle)
|
||||
query = DelSrcQuery(self.dbstate, self.uistate, object, the_lists)
|
||||
is_used = any(the_lists)
|
||||
return (query, is_used, object)
|
||||
|
||||
def edit(self, obj):
|
||||
for handle in self.selected_handles():
|
||||
source = self.dbstate.db.get_source_from_handle(handle)
|
||||
try:
|
||||
EditSource(self.dbstate, self.uistate, [], source)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def fast_merge(self, obj):
|
||||
mlist = self.selected_handles()
|
||||
|
||||
if len(mlist) != 2:
|
||||
msg = _("Cannot merge sources.")
|
||||
msg2 = _("Exactly two sources must be selected to perform a merge. "
|
||||
"A second source can be selected by holding down the "
|
||||
"control key while clicking on the desired source.")
|
||||
ErrorDialog(msg, msg2)
|
||||
else:
|
||||
import Merge
|
||||
Merge.MergeSources(self.dbstate, self.uistate, mlist[0], mlist[1])
|
||||
|
||||
def get_handle_from_gramps_id(self, gid):
|
||||
obj = self.dbstate.db.get_source_from_gramps_id(gid)
|
||||
if obj:
|
||||
return obj.get_handle()
|
||||
else:
|
||||
return None
|
171
src/plugins/view/view.gpr.py
Normal file
171
src/plugins/view/view.gpr.py
Normal file
@@ -0,0 +1,171 @@
|
||||
# encoding:utf-8
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2009 Benny Malengier
|
||||
#
|
||||
# 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$
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# default views of GRAMPS
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
register(VIEW,
|
||||
id = 'eventview',
|
||||
name = _("Event View"),
|
||||
description = _("The view showing all the events"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'eventview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_EVENT,
|
||||
viewclass = 'EventView',
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'familyview',
|
||||
name = _("Family View"),
|
||||
description = _("The view showing all families"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'familyview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_FAMILY,
|
||||
viewclass = 'FamilyView',
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'grampletview',
|
||||
name = _("Gramplet View"),
|
||||
description = _("The view allowing to see Gramplets"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'grampletview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_MISC,
|
||||
viewclass = 'GrampletView',
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'mediaview',
|
||||
name = _("Media View"),
|
||||
description = _("The view showing all the media objects"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'mediaview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_MEDIA,
|
||||
viewclass = 'MediaView',
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'noteview',
|
||||
name = _("Note View"),
|
||||
description = _("The view showing all the notes"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'noteview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_NOTE,
|
||||
viewclass = 'NoteView',
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'relview',
|
||||
name = _("Relationship View"),
|
||||
description = _("The view showing all relationships of the selected person"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'relview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_REL,
|
||||
viewclass = 'RelationshipView',
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'pedigreeview',
|
||||
name = _("Pedigree View"),
|
||||
description = _("The view showing an ancestor pedigree of the selected person"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'pedigreeview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_REL,
|
||||
viewclass = 'PedigreeView',
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'personview',
|
||||
name = _("Person View"),
|
||||
description = _("The view showing all people in the family tree"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'personview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_PERSON,
|
||||
viewclass = 'PersonView',
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'placeview',
|
||||
name = _("Place View"),
|
||||
description = _("The view showing all the places of the family tree"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'placeview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_PLACE,
|
||||
viewclass = 'PlaceView',
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'repoview',
|
||||
name = _("Repository View"),
|
||||
description = _("The view showing all the repositories"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'repoview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_REPO,
|
||||
viewclass = 'RepositoryView',
|
||||
)
|
||||
|
||||
register(VIEW,
|
||||
id = 'sourceview',
|
||||
name = _("Source View"),
|
||||
description = _("The view showing all the sources"),
|
||||
version = '1.0',
|
||||
status = STABLE,
|
||||
fname = 'sourceview.py',
|
||||
authors = [u"The GRAMPS project"],
|
||||
authors_email = ["http://gramps-project.org"],
|
||||
category = VIEW_SOURCE,
|
||||
viewclass = 'SourceView',
|
||||
)
|
Reference in New Issue
Block a user