Moved DeepConnections.py HeadlineNewsGramplet.py NoteGramplet.py PythonGramplet.py to gramps-addons
svn: r13808
This commit is contained in:
parent
bbe2b6da0c
commit
cb721e6ad3
@ -1,177 +0,0 @@
|
||||
# encoding: utf-8
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2009 Doug Blank <doug.blank@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gen.lib import EventType, FamilyRelType
|
||||
from BasicUtils import name_displayer
|
||||
from gen.plug import Gramplet
|
||||
from TransUtils import sgettext as _
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# The Gramplet
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class DeepConnectionsGramplet(Gramplet):
|
||||
"""
|
||||
Finds deep connections people the home person and the active person.
|
||||
"""
|
||||
def init(self):
|
||||
self.set_tooltip(_("Double-click name for details"))
|
||||
self.set_text(_("No Family Tree loaded."))
|
||||
self.set_use_markup(True)
|
||||
self.gui.get_container_widget().remove(self.gui.textview)
|
||||
vbox = gtk.VBox()
|
||||
hbox = gtk.HBox()
|
||||
pause_button = gtk.Button(_("Pause"))
|
||||
pause_button.connect("clicked", self.interrupt)
|
||||
continue_button = gtk.Button(_("Continue"))
|
||||
continue_button.connect("clicked", self.resume)
|
||||
hbox.pack_start(pause_button, True)
|
||||
hbox.pack_start(continue_button, True)
|
||||
vbox.pack_start(self.gui.textview, True)
|
||||
vbox.pack_start(hbox, False)
|
||||
self.gui.get_container_widget().add_with_viewport(vbox)
|
||||
vbox.show_all()
|
||||
|
||||
def get_relatives(self, person_handle, path):
|
||||
"""
|
||||
Gets all of the direct relatives of person_handle.
|
||||
"""
|
||||
retval = []
|
||||
person = self.dbstate.db.get_person_from_handle(person_handle)
|
||||
if person is None: return []
|
||||
family_list = person.get_family_handle_list()
|
||||
for family_handle in family_list:
|
||||
family = self.dbstate.db.get_family_from_handle(family_handle)
|
||||
|
||||
children = family.get_child_ref_list()
|
||||
retval.extend((child_ref.ref, (path, (_("child"), person_handle)))
|
||||
for child_ref in children)
|
||||
|
||||
husband = family.get_father_handle()
|
||||
if husband:
|
||||
retval += [(husband, (path, (_("husband"), person_handle)))]
|
||||
|
||||
wife = family.get_mother_handle()
|
||||
if wife:
|
||||
retval += [(wife, (path, (_("wife"), person_handle)))]
|
||||
|
||||
parent_family_list = person.get_parent_family_handle_list()
|
||||
for family_handle in parent_family_list:
|
||||
family = self.dbstate.db.get_family_from_handle(family_handle)
|
||||
|
||||
children = family.get_child_ref_list()
|
||||
retval.extend((child_ref.ref, (path, (_("child"), person_handle)))
|
||||
for child_ref in children)
|
||||
|
||||
husband = family.get_father_handle()
|
||||
if husband:
|
||||
retval += [(husband, (path, (_("father"), person_handle)))]
|
||||
|
||||
wife = family.get_mother_handle()
|
||||
if wife:
|
||||
retval += [(wife, (path, (_("mother"), person_handle)))]
|
||||
return retval
|
||||
|
||||
def active_changed(self, handle):
|
||||
"""
|
||||
Update the gramplet on active person change.
|
||||
"""
|
||||
self.update()
|
||||
|
||||
def pretty_print(self, path):
|
||||
"""
|
||||
Print a path to a person, with links.
|
||||
"""
|
||||
more_path, relation = path
|
||||
text, handle = relation
|
||||
person = self.dbstate.db.get_person_from_handle(handle)
|
||||
name = person.get_primary_name()
|
||||
if text != "self":
|
||||
self.append_text(_("\n who is a %s of ") % text)
|
||||
self.link(name_displayer.display_name(name), "Person", handle)
|
||||
if more_path is not None:
|
||||
self.pretty_print(more_path)
|
||||
|
||||
def main(self):
|
||||
"""
|
||||
Main method.
|
||||
"""
|
||||
self.total_relations_found = 0
|
||||
yield True
|
||||
default_person = self.dbstate.db.get_default_person()
|
||||
active_person = self.dbstate.get_active_person()
|
||||
if default_person == None:
|
||||
self.set_text(_("No Home Person set."))
|
||||
return
|
||||
if active_person == None:
|
||||
self.set_text(_("No Active Person set."))
|
||||
return
|
||||
self.cache = set()
|
||||
self.queue = [(default_person.handle, (None, (_("self"), default_person.handle)))]
|
||||
default_name = default_person.get_primary_name()
|
||||
active_name = active_person.get_primary_name()
|
||||
self.set_text("")
|
||||
self.render_text((_("Looking for relationship between\n") +
|
||||
_(" <b>%s</b> (Home Person) and\n") +
|
||||
_(" <b>%s</b> (Active Person)...\n")) %
|
||||
(name_displayer.display_name(default_name),
|
||||
name_displayer.display_name(active_name)))
|
||||
yield True
|
||||
while self.queue:
|
||||
current_handle, current_path = self.queue.pop(0)
|
||||
if current_handle == active_person.handle:
|
||||
self.total_relations_found += 1
|
||||
self.append_text(_("Found relation #%d: \n ") % self.total_relations_found)
|
||||
|
||||
self.link(name_displayer.display_name(active_name), "Person", active_person.handle)
|
||||
self.pretty_print(current_path)
|
||||
self.append_text("\n")
|
||||
if default_person.handle != active_person.handle:
|
||||
self.append_text(_("Paused.\nPress Continue to search for additional relations.\n"))
|
||||
self.pause()
|
||||
yield False
|
||||
else:
|
||||
break
|
||||
elif current_handle in self.cache:
|
||||
continue
|
||||
self.cache.add(current_handle)
|
||||
relatives = self.get_relatives(current_handle, current_path)
|
||||
for (person_handle, path) in relatives:
|
||||
if person_handle is not None and person_handle not in self.cache:
|
||||
self.queue.append( (person_handle, path))
|
||||
yield True
|
||||
self.append_text(_("\nSearch completed. %d relations found.") % self.total_relations_found)
|
||||
yield False
|
@ -1,267 +0,0 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2007-2009 Douglas S. Blank <doug.blank@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# $Id$
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import re
|
||||
import gobject
|
||||
import urllib
|
||||
from xml.dom import minidom, Node
|
||||
# FIXME For Python 3:
|
||||
# Change:
|
||||
# import urllib
|
||||
# To:
|
||||
# import urllib.request
|
||||
# Change:
|
||||
# url_info = urllib.urlopen(URL)
|
||||
# To:
|
||||
# url_info = urllib.request.urlopen(URL)
|
||||
import sys
|
||||
from htmlentitydefs import name2codepoint as n2cp
|
||||
import re
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gen.plug import Gramplet
|
||||
from const import URL_WIKISTRING
|
||||
from TransUtils import sgettext as _
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Local functions
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def substitute(match):
|
||||
ent = match.group(2)
|
||||
if match.group(1) == "#":
|
||||
return unichr(int(ent))
|
||||
else:
|
||||
cp = n2cp.get(ent)
|
||||
if cp:
|
||||
return unichr(cp)
|
||||
else:
|
||||
return match.group()
|
||||
|
||||
def decode_html(string):
|
||||
entity_re = re.compile("&(#?)(\d{1,5}|\w{1,8});")
|
||||
return entity_re.subn(substitute, string)[0]
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Gramplet class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class HeadlineNewsGramplet(Gramplet):
|
||||
"""
|
||||
Headlines News Gramplet reads the Headline News every hour.
|
||||
"""
|
||||
RAW = URL_WIKISTRING + "%s&action=raw"
|
||||
URL = URL_WIKISTRING + "%s"
|
||||
|
||||
def init(self):
|
||||
"""
|
||||
Initialize gramplet. Start up update timer.
|
||||
"""
|
||||
self.limit = 5
|
||||
# Description, Type, URL, Pretty URL for User
|
||||
self.feeds = [
|
||||
("Gramps Wiki Headline News", "wiki", (self.RAW % "HeadlineNews"), (self.URL % "HeadlineNews")),
|
||||
("Gramps Blog Comments", "rss", "http://blog.gramps-project.org/?feed=comments-rss2", None),
|
||||
("Gramps Blog Posts", "rss", "http://blog.gramps-project.org/?feed=rss", None),
|
||||
("Gramps Wiki Changes", "rss", "http://www.gramps-project.org/wiki/index.php?title=Special:RecentChanges&feed=rss", None),
|
||||
("Gramps Bugtracker Issues", "rss", "http://www.gramps-project.org/bugs/issues_rss.php?key=ece7d21451d76337acf776c9a4384773", None),
|
||||
("Gramps SVN Commits", "rss", "http://cia.vc/stats/project/Gramps/.rss", None),
|
||||
]
|
||||
self.set_tooltip(_("Read Gramps headline news"))
|
||||
self.update_interval = 3600 * 1000 # in miliseconds (1 hour)
|
||||
self.set_use_markup(True)
|
||||
self.set_wrap(False)
|
||||
self.set_text(_("No Family Tree loaded."))
|
||||
self.timer = gobject.timeout_add(self.update_interval,
|
||||
self.update_by_timer)
|
||||
|
||||
def update_by_timer(self):
|
||||
"""
|
||||
Update, and return True to continually update on interval.
|
||||
"""
|
||||
self.update()
|
||||
return True # keep updating!
|
||||
|
||||
def main(self):
|
||||
self.set_text("Loading Gramps Headline News...\n")
|
||||
fresh = True
|
||||
yield True
|
||||
for (feed_description, feed_type, feed_url, pretty_url) in self.feeds:
|
||||
fp = urllib.urlopen(feed_url)
|
||||
if feed_type == "wiki":
|
||||
text = fp.read()
|
||||
if fresh:
|
||||
self.clear_text()
|
||||
fresh = False
|
||||
self.render_text("""<u><b>%s</b></u> [<a href="%s">wiki</a>]\n""" % (feed_description, pretty_url))
|
||||
self.render_text(self.decode_wiki(text).strip())
|
||||
self.append_text("\n")
|
||||
yield True
|
||||
elif feed_type == "rss":
|
||||
try:
|
||||
xmldoc = minidom.parse(fp)
|
||||
except Exception, e:
|
||||
print "Headline News Gramplet Error: RSS parse failed on '%s': %s" % (feed_description, e)
|
||||
continue
|
||||
if fresh:
|
||||
self.clear_text()
|
||||
fresh = False
|
||||
self.render_text("""<u><b>%s</b></u> [<a href="%s">RSS</a>]\n""" % (feed_description, feed_url))
|
||||
yield True
|
||||
rootNode = xmldoc.documentElement
|
||||
for node in rootNode.childNodes:
|
||||
#print "> ", node.nodeName
|
||||
if (node.nodeName == "channel"):
|
||||
count = 1
|
||||
for node2 in node.childNodes:
|
||||
if count > 5: break
|
||||
if (node2.nodeName == "item"):
|
||||
title = ""
|
||||
link = ""
|
||||
desc = u""
|
||||
# Gather up the data:
|
||||
for item_node in node2.childNodes:
|
||||
#print "---> ", item_node.nodeName
|
||||
if (item_node.nodeName == "title"):
|
||||
for text_node in item_node.childNodes:
|
||||
if (text_node.nodeType == node.TEXT_NODE):
|
||||
title += text_node.nodeValue
|
||||
elif (item_node.nodeName == "link"):
|
||||
for text_node in item_node.childNodes:
|
||||
if (text_node.nodeType == node.TEXT_NODE):
|
||||
link += text_node.nodeValue
|
||||
elif (item_node.nodeName == "description"):
|
||||
for text_node in item_node.childNodes:
|
||||
if (text_node.nodeType == node.TEXT_NODE):
|
||||
desc += text_node.nodeValue
|
||||
if title:
|
||||
if link:
|
||||
self.render_text(" %d. " % count)
|
||||
self.link(title, "URL", link, tooltip=link)
|
||||
else:
|
||||
self.render_text(" %d. %s" % (count, title))
|
||||
self.append_text(" - ")
|
||||
self.append_text(self.first_line(desc))
|
||||
self.append_text("\n")
|
||||
count += 1
|
||||
yield True
|
||||
self.append_text("\n")
|
||||
self.append_text("", scroll_to="begin")
|
||||
|
||||
def first_line(self, text):
|
||||
text = self.strip_html(text)
|
||||
text = decode_html(text)
|
||||
text = text.split("\n")[0]
|
||||
if len(text) > 30:
|
||||
text = text[:30]
|
||||
return text + "..."
|
||||
|
||||
def strip_html(self, text):
|
||||
text = text.replace("nbsp;", " ")
|
||||
retval = u""
|
||||
last_c = None
|
||||
state = "plain"
|
||||
for c in text:
|
||||
if c == "<":
|
||||
state = "skip"
|
||||
if state == "plain":
|
||||
if c in ["\t", " ", "\n"]:
|
||||
if (c == last_c):
|
||||
continue
|
||||
retval += c
|
||||
last_c = c
|
||||
if c == ">":
|
||||
state = "plain"
|
||||
return retval
|
||||
|
||||
def decode_wiki(self, text):
|
||||
# final text
|
||||
text = text.replace("<BR>", "\n")
|
||||
while "\n\n\n" in text:
|
||||
text = text.replace("\n\n\n", "\n\n")
|
||||
text = text.strip()
|
||||
## Wiki text:
|
||||
## Templates:
|
||||
pattern = '{{.*?}}'
|
||||
matches = re.findall(pattern, text)
|
||||
for match in matches:
|
||||
page = match[2:-2]
|
||||
oldtext = match
|
||||
if "|" in page:
|
||||
template, heading, body = page.split("|", 2)
|
||||
if template.lower() == "release":
|
||||
newtext = "Gramps " + heading + " released.\n\n"
|
||||
else:
|
||||
#newtext = "<B>%s</B>\n\n" % heading
|
||||
newtext = ""
|
||||
text = text.replace(oldtext, newtext)
|
||||
### Internal wiki URL with title:
|
||||
pattern = re.compile('\[\[(.*?)\|(.*?)\]\]')
|
||||
matches = pattern.findall(text)
|
||||
for (g1, g2) in matches:
|
||||
text = text.replace("[[%s|%s]]" % (g1, g2),
|
||||
("""<A HREF="%s">%s</A>""" %
|
||||
(self.wiki(g1), self.nice_title(g2))))
|
||||
### Internal wiki URL:
|
||||
pattern = re.compile('\[\[(.*?)\]\]')
|
||||
matches = pattern.findall(text)
|
||||
for match in matches:
|
||||
text = text.replace("[[%s]]" % match,
|
||||
("""<A HREF="%s">%s</A>""" %
|
||||
(self.wiki(match), self.nice_title(match))))
|
||||
### URL with title:
|
||||
pattern = re.compile('\[http\:\/\/(.*?) (.*?)\]')
|
||||
matches = pattern.findall(text)
|
||||
for (g1, g2) in matches:
|
||||
text = text.replace("[http://%s %s]" % (g1, g2),
|
||||
("""<A HREF="http://%s">%s</A>""" %
|
||||
(g1, g2)))
|
||||
### URL:
|
||||
pattern = re.compile('\[http\:\/\/(.*?)\]')
|
||||
matches = pattern.findall(text)
|
||||
count = 1
|
||||
for g1 in matches:
|
||||
text = text.replace("[http://%s]" % (g1),
|
||||
("""<A HREF="http://%s">%s</A>""" %
|
||||
(g1, ("[%d]" % count))))
|
||||
count += 1
|
||||
### Bold:
|
||||
pattern = re.compile("'''(.*?)'''")
|
||||
matches = pattern.findall(text)
|
||||
for match in matches:
|
||||
text = text.replace("'''%s'''" % match, "<B>%s</B>" % match)
|
||||
return text
|
||||
|
||||
def wiki(self, title):
|
||||
return (self.URL % title)
|
||||
|
||||
def nice_title(self, title):
|
||||
return title.replace("_", " ")
|
@ -15,7 +15,6 @@ pkgdata_PYTHON = \
|
||||
FaqGramplet.py \
|
||||
GivenNameGramplet.py \
|
||||
gramplet.gpr.py \
|
||||
HeadlineNewsGramplet.py \
|
||||
PedigreeGramplet.py \
|
||||
QuickViewGramplet.py \
|
||||
RelativeGramplet.py \
|
||||
|
@ -1,257 +0,0 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2007-2009 Douglas S. Blank <doug.blank@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# $Id$
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import gtk
|
||||
import pango
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gen.plug import Gramplet
|
||||
from BasicUtils import name_displayer
|
||||
from TransUtils import sgettext as _
|
||||
from gui.widgets import StyledTextEditor
|
||||
from gui.editors import EditPerson, EditFamily
|
||||
from gen.lib import StyledText, Note
|
||||
import Errors
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Gramplet class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class NoteGramplet(Gramplet):
|
||||
"""
|
||||
Gramplet that gives simplified interface to a Person's primary note.
|
||||
"""
|
||||
def init(self):
|
||||
rows = gtk.VBox()
|
||||
self.dirty = False
|
||||
self.dirty_person = None
|
||||
|
||||
# Active person: Name
|
||||
row = gtk.HBox()
|
||||
label = gtk.Label()
|
||||
label.set_text("<b>%s</b>: " % _("Active person"))
|
||||
label.set_use_markup(True)
|
||||
label.set_alignment(0.0, 0.5)
|
||||
row.pack_start(label, False)
|
||||
|
||||
apw = gtk.Label()
|
||||
self.active_person_widget = apw
|
||||
apw.set_alignment(0.0, 0.5)
|
||||
apw.set_use_markup(True)
|
||||
row.pack_start(apw, False)
|
||||
|
||||
# Add edit for person and family
|
||||
icon = gtk.STOCK_EDIT
|
||||
size = gtk.ICON_SIZE_MENU
|
||||
button = gtk.Button()
|
||||
image = gtk.Image()
|
||||
image.set_from_stock(icon, size)
|
||||
button.add(image)
|
||||
button.set_relief(gtk.RELIEF_NONE)
|
||||
button.connect("clicked", self.edit_person)
|
||||
self.active_person_edit = button
|
||||
row.pack_start(button, False)
|
||||
|
||||
label = gtk.Label()
|
||||
label.set_text(" %s: " % _("Family"))
|
||||
self.active_family_label = label
|
||||
row.pack_start(label, False)
|
||||
|
||||
button = gtk.Button()
|
||||
image = gtk.Image()
|
||||
image.set_from_stock(icon, size)
|
||||
button.add(image)
|
||||
button.set_relief(gtk.RELIEF_NONE)
|
||||
button.connect("clicked", self.edit_family)
|
||||
self.active_family_edit = button
|
||||
row.pack_start(button, False)
|
||||
|
||||
rows.pack_start(row, False)
|
||||
|
||||
row = self.build_interface()
|
||||
self.note_buffer = self.texteditor.textbuffer
|
||||
self.note_buffer.connect("changed", self.mark_dirty)
|
||||
rows.pack_start(row, True)
|
||||
|
||||
# Save and Abandon
|
||||
row = gtk.HBox()
|
||||
button = gtk.Button(_("Save"))
|
||||
button.connect("clicked", self.save_data_edit)
|
||||
row.pack_start(button, True)
|
||||
button = gtk.Button(_("Abandon"))
|
||||
button.connect("clicked", self.abandon_data_edit)
|
||||
row.pack_start(button, True)
|
||||
rows.pack_start(row, False)
|
||||
|
||||
self.gui.get_container_widget().remove(self.gui.textview)
|
||||
self.gui.get_container_widget().add_with_viewport(rows)
|
||||
rows.show_all()
|
||||
self.clear_data_entry(None)
|
||||
|
||||
def flow_changed(self, active):
|
||||
"""
|
||||
Changes the wrap/font of text flow.
|
||||
"""
|
||||
if active:
|
||||
# Set the text style to monospace
|
||||
self.texteditor.set_wrap_mode(gtk.WRAP_NONE)
|
||||
self.texteditor.modify_font(pango.FontDescription("monospace"))
|
||||
else:
|
||||
# Set the text style to normal
|
||||
self.texteditor.set_wrap_mode(gtk.WRAP_WORD)
|
||||
self.texteditor.modify_font(pango.FontDescription("normal"))
|
||||
|
||||
def build_interface(self):
|
||||
"""
|
||||
Based on src/gui/editors/editnote.py
|
||||
"""
|
||||
vbox = gtk.VBox()
|
||||
self.texteditor = StyledTextEditor()
|
||||
# create a formatting toolbar
|
||||
vbox.pack_start(self.texteditor.get_toolbar(),
|
||||
expand=False, fill=False)
|
||||
vbox.pack_start(self.texteditor, True)
|
||||
self.flow_changed(False)
|
||||
return vbox
|
||||
|
||||
def main(self): # return false finishes
|
||||
if self.dirty:
|
||||
return
|
||||
self.active_person_edit.hide()
|
||||
self.active_family_edit.hide()
|
||||
self.active_family_label.hide()
|
||||
self.note_buffer.set_text(StyledText())
|
||||
active_person = self.dbstate.get_active_person()
|
||||
self.dirty_person = active_person
|
||||
self.dirty_family = None
|
||||
if active_person:
|
||||
self.active_person_edit.show()
|
||||
self.active_family_edit.hide()
|
||||
self.active_family_label.hide()
|
||||
# Fill in current person edits:
|
||||
name = name_displayer.display(active_person)
|
||||
self.active_person_widget.set_text("<i>%s</i> " % name)
|
||||
self.active_person_widget.set_use_markup(True)
|
||||
# Note:
|
||||
self.note = None
|
||||
note_list = active_person.get_referenced_note_handles()
|
||||
for (classname, note_handle) in note_list:
|
||||
note_obj = self.dbstate.db.get_note_from_handle(note_handle)
|
||||
if note_obj.get_type() == _("Person Note"):
|
||||
self.note = note_obj
|
||||
break
|
||||
if self.note is None:
|
||||
self.note = Note()
|
||||
self.texteditor.set_text(self.note.get_styledtext())
|
||||
self.flow_changed(self.note.get_format())
|
||||
# Family button:
|
||||
family_list = active_person.get_family_handle_list()
|
||||
if len(family_list) > 0:
|
||||
self.dirty_family = self.dbstate.db.get_family_from_handle(family_list[0])
|
||||
self.active_family_edit.show()
|
||||
self.active_family_label.show()
|
||||
else:
|
||||
family_list = active_person.get_parent_family_handle_list()
|
||||
if len(family_list) > 0:
|
||||
self.dirty_family = self.dbstate.db.get_family_from_handle(family_list[0])
|
||||
self.active_family_edit.show()
|
||||
self.active_family_label.show()
|
||||
else:
|
||||
self.clear_data_entry(None)
|
||||
self.active_person_edit.hide()
|
||||
self.active_family_edit.hide()
|
||||
self.active_family_label.hide()
|
||||
self.dirty = False
|
||||
|
||||
def clear_data_entry(self, obj):
|
||||
self.note_buffer.set_text(StyledText())
|
||||
self.flow_changed(False)
|
||||
|
||||
def db_changed(self):
|
||||
"""
|
||||
If person or family changes, the relatives of active person might have
|
||||
changed
|
||||
"""
|
||||
self.dirty = False
|
||||
self.dirty_person = None
|
||||
self.clear_data_entry(None)
|
||||
self.texteditor.set_editable(not self.dbstate.db.readonly)
|
||||
self.update()
|
||||
|
||||
def active_changed(self, handle):
|
||||
self.update()
|
||||
|
||||
def mark_dirty(self, obj):
|
||||
self.dirty = True
|
||||
|
||||
def abandon_data_edit(self, obj):
|
||||
self.dirty = False
|
||||
self.update()
|
||||
|
||||
def edit_callback(self, person):
|
||||
self.dirty = False
|
||||
self.update()
|
||||
|
||||
def edit_person(self, obj):
|
||||
try:
|
||||
EditPerson(self.gui.dbstate,
|
||||
self.gui.uistate, [],
|
||||
self.dirty_person,
|
||||
callback=self.edit_callback)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def edit_family(self, obj):
|
||||
try:
|
||||
EditFamily(self.gui.dbstate,
|
||||
self.gui.uistate, [],
|
||||
self.dirty_family)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
|
||||
def save_data_edit(self, obj):
|
||||
if self.dirty:
|
||||
person = self.dirty_person
|
||||
text = self.texteditor.get_text()
|
||||
self.note.set_styledtext(text)
|
||||
trans = self.dbstate.db.transaction_begin()
|
||||
if not self.note.get_handle():
|
||||
self.note.set_type(_("Person Note"))
|
||||
self.dbstate.db.add_note(self.note, trans)
|
||||
person.add_note(self.note.get_handle())
|
||||
self.dbstate.db.commit_person(person, trans)
|
||||
msg = _("Add Note")
|
||||
else:
|
||||
if not self.note.get_gramps_id():
|
||||
self.note.set_gramps_id(self.dbstate.db.find_next_note_gramps_id())
|
||||
self.dbstate.db.commit_note(self.note, trans)
|
||||
msg = _("Edit Note")
|
||||
self.dbstate.db.transaction_commit(trans, msg)
|
||||
self.dirty = False
|
@ -1,163 +0,0 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2007-2009 Douglas S. Blank <doug.blank@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# $Id$
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import sys
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gen.plug import Gramplet
|
||||
from TransUtils import sgettext as _
|
||||
import gen
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Gramplet class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class PythonGramplet(Gramplet):
|
||||
def init(self):
|
||||
import gc
|
||||
gc.set_debug(gc.DEBUG_UNCOLLECTABLE|gc.DEBUG_OBJECTS|gc.DEBUG_SAVEALL)
|
||||
self.prompt = ">"
|
||||
self.previous = ""
|
||||
self.set_tooltip(_("Enter Python expressions"))
|
||||
self.gc = gc
|
||||
self.env = {"dbstate": self.gui.dbstate,
|
||||
"uistate": self.gui.uistate,
|
||||
"gc": self.gc,
|
||||
"self": self,
|
||||
_("class name|Date"): gen.lib.Date,
|
||||
}
|
||||
# GUI setup:
|
||||
self.gui.textview.set_editable(True)
|
||||
self.set_text("Python %s\n%s " % (sys.version, self.prompt))
|
||||
self.gui.textview.connect('key-press-event', self.on_key_press)
|
||||
|
||||
def post_init(self):
|
||||
self.disconnect("active-changed")
|
||||
|
||||
def format_exception(self, max_tb_level=10):
|
||||
retval = ''
|
||||
cla, exc, trbk = sys.exc_info()
|
||||
retval += _("Error") + (" : %s %s" %(cla, exc))
|
||||
return retval
|
||||
|
||||
def process_command(self, command):
|
||||
# update states, in case of change:
|
||||
self.env["dbstate"] = self.gui.dbstate
|
||||
self.env["uistate"] = self.gui.uistate
|
||||
_retval = None
|
||||
if "_retval" in self.env:
|
||||
del self.env["_retval"]
|
||||
if self.previous:
|
||||
if command:
|
||||
self.previous += "\n" + command
|
||||
return
|
||||
else:
|
||||
exp = self.previous
|
||||
else:
|
||||
exp = command.strip()
|
||||
try:
|
||||
_retval = eval(exp, self.env)
|
||||
self.previous = ""
|
||||
except:
|
||||
try:
|
||||
exec exp in self.env
|
||||
self.previous = ""
|
||||
self.prompt = ">"
|
||||
except SyntaxError:
|
||||
if command:
|
||||
self.previous = exp
|
||||
self.prompt = "-"
|
||||
else:
|
||||
self.previous = ""
|
||||
self.prompt = ">"
|
||||
_retval = self.format_exception()
|
||||
except:
|
||||
self.previous = ""
|
||||
self.prompt = ">"
|
||||
_retval = self.format_exception()
|
||||
if "_retval" in self.env:
|
||||
_retval = self.env["_retval"]
|
||||
return _retval
|
||||
|
||||
def on_key_press(self, widget, event):
|
||||
import gtk
|
||||
if (event.keyval == gtk.keysyms.Home or
|
||||
((event.keyval == gtk.keysyms.a and
|
||||
event.get_state() & gtk.gdk.CONTROL_MASK))):
|
||||
buffer = widget.get_buffer()
|
||||
cursor_pos = buffer.get_property("cursor-position")
|
||||
iter = buffer.get_iter_at_offset(cursor_pos)
|
||||
line_cnt = iter.get_line()
|
||||
start = buffer.get_iter_at_line(line_cnt)
|
||||
start.forward_chars(2)
|
||||
buffer.place_cursor(start)
|
||||
return True
|
||||
elif (event.keyval == gtk.keysyms.End or
|
||||
(event.keyval == gtk.keysyms.e and
|
||||
event.get_state() & gtk.gdk.CONTROL_MASK)):
|
||||
buffer = widget.get_buffer()
|
||||
end = buffer.get_end_iter()
|
||||
buffer.place_cursor(end)
|
||||
return True
|
||||
elif event.keyval == gtk.keysyms.Return:
|
||||
echo = False
|
||||
buffer = widget.get_buffer()
|
||||
cursor_pos = buffer.get_property("cursor-position")
|
||||
iter = buffer.get_iter_at_offset(cursor_pos)
|
||||
line_cnt = iter.get_line()
|
||||
start = buffer.get_iter_at_line(line_cnt)
|
||||
line_len = iter.get_chars_in_line()
|
||||
buffer_cnt = buffer.get_line_count()
|
||||
if (buffer_cnt - line_cnt) > 1:
|
||||
line_len -= 1
|
||||
echo = True
|
||||
end = buffer.get_iter_at_line_offset(line_cnt, line_len)
|
||||
line = buffer.get_text(start, end)
|
||||
self.append_text("\n")
|
||||
if line.startswith(self.prompt):
|
||||
line = line[2:]
|
||||
else:
|
||||
self.append_text("%s " % self.prompt)
|
||||
end = buffer.get_end_iter()
|
||||
buffer.place_cursor(end)
|
||||
return True
|
||||
if echo:
|
||||
self.append_text(("%s " % self.prompt) + line)
|
||||
end = buffer.get_end_iter()
|
||||
buffer.place_cursor(end)
|
||||
return True
|
||||
_retval = self.process_command(line)
|
||||
if _retval is not None:
|
||||
self.append_text("%s\n" % str(_retval))
|
||||
self.append_text("%s " % self.prompt)
|
||||
end = buffer.get_end_iter()
|
||||
buffer.place_cursor(end)
|
||||
return True
|
||||
return False
|
@ -73,16 +73,6 @@ register(GRAMPLET,
|
||||
gramplet_title=_("Calendar"),
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id = "Deep Connections Gramplet",
|
||||
name =_("Deep Connections Gramplet"),
|
||||
status = STABLE,
|
||||
fname="DeepConnections.py",
|
||||
height = 230,
|
||||
expand = True,
|
||||
gramplet = 'DeepConnectionsGramplet',
|
||||
gramplet_title = _("Deep Connections"))
|
||||
|
||||
register(GRAMPLET,
|
||||
id = "Descendant Gramplet",
|
||||
name=_("Descendant Gramplet"),
|
||||
@ -131,34 +121,6 @@ register(GRAMPLET,
|
||||
gramplet_title=_("Given Name Cloud"),
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Headline News Gramplet",
|
||||
name=_("Headline News Gramplet"),
|
||||
status = STABLE,
|
||||
fname="HeadlineNewsGramplet.py",
|
||||
height=300,
|
||||
expand=True,
|
||||
gramplet = 'HeadlineNewsGramplet',
|
||||
gramplet_title=_("Headline News"),
|
||||
#gramps="3.1.0",
|
||||
version="1.0.2",
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Note Gramplet",
|
||||
name=_("Note Gramplet"),
|
||||
status = STABLE,
|
||||
fname="NoteGramplet.py",
|
||||
height=100,
|
||||
expand=True,
|
||||
gramplet = 'NoteGramplet',
|
||||
gramplet_title=_("Note"),
|
||||
detached_width = 500,
|
||||
detached_height = 400,
|
||||
#gramps="3.1.0",
|
||||
version="1.0.0",
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Pedigree Gramplet",
|
||||
name=_("Pedigree Gramplet"),
|
||||
@ -185,16 +147,6 @@ register(GRAMPLET,
|
||||
#gramps="3.1.0",
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Python Gramplet",
|
||||
name=_("Python Gramplet"),
|
||||
status = STABLE,
|
||||
fname="PythonGramplet.py",
|
||||
height=250,
|
||||
gramplet = 'PythonGramplet',
|
||||
gramplet_title=_("Python Shell"),
|
||||
)
|
||||
|
||||
register(GRAMPLET,
|
||||
id="Quick View Gramplet",
|
||||
name=_("Quick View Gramplet"),
|
||||
|
Loading…
Reference in New Issue
Block a user