Fixed major issue with db/dbstate
svn: r9580
This commit is contained in:
parent
5f077e4795
commit
fe8a8d4986
@ -28,11 +28,14 @@ __author__ = "Doug Blank"
|
||||
__revision__ = "$Revision: $"
|
||||
|
||||
import gtk
|
||||
import PageView
|
||||
import const
|
||||
import gobject
|
||||
import traceback
|
||||
import time
|
||||
import pango
|
||||
|
||||
import Errors
|
||||
import const
|
||||
import PageView
|
||||
|
||||
AVAILABLE_GADGETS = []
|
||||
|
||||
@ -64,24 +67,41 @@ def make_requested_gadget(viewpage, name, opts, dbstate, uistate):
|
||||
return gui
|
||||
return None
|
||||
|
||||
class LinkTag(gtk.TextTag):
|
||||
lid = 0
|
||||
def __init__(self, buffer):
|
||||
LinkTag.lid += 1
|
||||
gtk.TextTag.__init__(self, str(LinkTag.lid))
|
||||
tag_table = buffer.get_tag_table()
|
||||
self.set_property('foreground', "#0000ff")
|
||||
self.set_property('underline', pango.UNDERLINE_SINGLE)
|
||||
tag_table.add(self)
|
||||
|
||||
class Gadget(object):
|
||||
def __init__(self, gui):
|
||||
self._idle_id = 0
|
||||
self._generator = None
|
||||
self._need_to_update = False
|
||||
self._tags = []
|
||||
self.link_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)
|
||||
self.standard_cursor = gtk.gdk.Cursor(gtk.gdk.XTERM)
|
||||
self.gui = gui
|
||||
self.dbstate = gui.dbstate
|
||||
self.init()
|
||||
self.dbstate.connect('database-changed', self._db_changed)
|
||||
self.dbstate.connect('active-changed', self.active_changed)
|
||||
self.gui.textview.connect('button-press-event',
|
||||
self.on_button_press)
|
||||
self.gui.textview.connect('motion-notify-event',
|
||||
self.on_motion)
|
||||
|
||||
def active_changed(self, handle):
|
||||
pass
|
||||
|
||||
def _db_changed(self, dbstate):
|
||||
def _db_changed(self, db):
|
||||
if debug: print "%s is _connecting" % self.gui.title
|
||||
self.dbstate = dbstate
|
||||
self.gui.dbstate = dbstate
|
||||
self.dbstate.db = db
|
||||
self.gui.dbstate.db = db
|
||||
self.db_changed()
|
||||
self.update()
|
||||
|
||||
@ -144,6 +164,48 @@ class Gadget(object):
|
||||
self.gui.buffer.insert(end, text)
|
||||
self.gui.textview.scroll_to_mark(mark, 0.0, True, 0, 0)
|
||||
|
||||
def on_motion(self, view, event):
|
||||
buffer_location = view.window_to_buffer_coords(gtk.TEXT_WINDOW_TEXT,
|
||||
int(event.x),
|
||||
int(event.y))
|
||||
iter = view.get_iter_at_location(*buffer_location)
|
||||
for (tag, person_handle) in self._tags:
|
||||
if iter.has_tag(tag):
|
||||
view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(self.link_cursor)
|
||||
return False # handle event further, if necessary
|
||||
view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(self.standard_cursor)
|
||||
return False # handle event further, if necessary
|
||||
|
||||
def on_button_press(self, view, event):
|
||||
from Editors import EditPerson
|
||||
buffer_location = view.window_to_buffer_coords(gtk.TEXT_WINDOW_TEXT,
|
||||
int(event.x),
|
||||
int(event.y))
|
||||
iter = view.get_iter_at_location(*buffer_location)
|
||||
for (tag, person_handle) in self._tags:
|
||||
if iter.has_tag(tag):
|
||||
person = self.dbstate.db.get_person_from_handle(person_handle)
|
||||
if event.button == 1:
|
||||
if event.type == gtk.gdk._2BUTTON_PRESS:
|
||||
try:
|
||||
EditPerson(self.gui.dbstate, self.gui.uistate, [], person)
|
||||
except Errors.WindowActiveError:
|
||||
pass
|
||||
else:
|
||||
self.gui.dbstate.change_active_person(person)
|
||||
return True # handled event
|
||||
return False # did not handle event
|
||||
|
||||
def link(self, text, data):
|
||||
buffer = self.gui.buffer
|
||||
iter = buffer.get_end_iter()
|
||||
offset = buffer.get_char_count()
|
||||
self.append_text(text)
|
||||
start = buffer.get_iter_at_offset(offset)
|
||||
end = buffer.get_end_iter()
|
||||
self._tags.append((LinkTag(buffer),data))
|
||||
buffer.apply_tag(self._tags[-1][0], start, end)
|
||||
|
||||
def insert_text(self, text):
|
||||
self.gui.buffer.insert_at_cursor(text)
|
||||
|
||||
@ -203,21 +265,29 @@ class GuiGadget:
|
||||
del self.viewpage.frame_map[str(self.mainframe)]
|
||||
self.mainframe.destroy()
|
||||
|
||||
def change_state(self, obj):
|
||||
if self.state == "maximized":
|
||||
def set_state(self, state):
|
||||
self.state = state
|
||||
if state == "minimized":
|
||||
self.scrolledwindow.hide()
|
||||
self.xml.get_widget('gvstateimage').set_from_stock(gtk.STOCK_ADD,
|
||||
gtk.ICON_SIZE_MENU)
|
||||
self.state = "minimized"
|
||||
column = self.mainframe.get_parent() # column
|
||||
expand,fill,padding,pack = column.query_child_packing(self.mainframe)
|
||||
column.set_child_packing(self.mainframe,False,fill,padding,pack)
|
||||
|
||||
else:
|
||||
self.scrolledwindow.show()
|
||||
self.xml.get_widget('gvstateimage').set_from_stock(gtk.STOCK_REMOVE,
|
||||
gtk.ICON_SIZE_MENU)
|
||||
self.state = "maximized"
|
||||
if self.expand:
|
||||
column = self.mainframe.get_parent() # column
|
||||
expand,fill,padding,pack = column.query_child_packing(self.mainframe)
|
||||
column.set_child_packing(self.mainframe,(not expand),fill,padding,pack)
|
||||
column.set_child_packing(self.mainframe,self.expand,fill,padding,pack)
|
||||
|
||||
def change_state(self, obj):
|
||||
if self.state == "maximized":
|
||||
self.set_state("minimized")
|
||||
else:
|
||||
self.set_state("maximized")
|
||||
|
||||
def set_properties(self, obj):
|
||||
self.expand = not self.expand
|
||||
@ -236,7 +306,6 @@ class GuiGadget:
|
||||
self.buffer.set_text(text)
|
||||
|
||||
|
||||
|
||||
class MyGrampsView(PageView.PageView):
|
||||
"""
|
||||
MyGrampsView interface
|
||||
@ -284,16 +353,18 @@ class MyGrampsView(PageView.PageView):
|
||||
# get the user's gadgets from .gramps
|
||||
# and/or from open database
|
||||
# Load the user's gadgets:
|
||||
for (name, opts) in [('Stats Gadget', {}),
|
||||
('Top Surnames Gadget', {}),
|
||||
#('Families Gadget', {}),
|
||||
#('Families Gadget', {"title": "My Peeps"}),
|
||||
('Hello World Gadget', {}),
|
||||
('Log Gadget', {}),
|
||||
('Shell Gadget', {}),
|
||||
('Python Gadget', {}),
|
||||
#('Events Gadget', {}),
|
||||
]:
|
||||
for (name, opts) in [
|
||||
('Stats Gadget', {}),
|
||||
('Top Surnames Gadget', {}),
|
||||
#('Families Gadget', {}),
|
||||
#('Families Gadget', {"title": "My Peeps"}),
|
||||
('Hello World Gadget', {}),
|
||||
('Shell Gadget', {}),
|
||||
('Python Gadget', {}),
|
||||
('TODO Gadget', {}),
|
||||
('Log Gadget', {}),
|
||||
#('Events Gadget', {}),
|
||||
]:
|
||||
all_opts = get_gadget_opts(name, opts)
|
||||
if "title" not in all_opts:
|
||||
all_opts["title"] = "Untitled Gadget"
|
||||
@ -314,7 +385,6 @@ class MyGrampsView(PageView.PageView):
|
||||
print "Can't make gadget of type '%s'." % name
|
||||
else:
|
||||
print "Ignoring duplicate named gadget '%s'." % all_opts["title"]
|
||||
|
||||
# put the gadgets where they go:
|
||||
cnt = 0
|
||||
for gadget in self.gadget_map.values():
|
||||
@ -325,13 +395,17 @@ class MyGrampsView(PageView.PageView):
|
||||
else:
|
||||
# else, spread them out:
|
||||
pos = cnt % len(self.columns)
|
||||
if gadget.state == "minimized": # starts max, change to min it
|
||||
gadget.state = "maximized"
|
||||
gadget.change_state(gadget) # minimize it
|
||||
# to make as big as possible, set to True:
|
||||
# GTK BUG: can't minimize:
|
||||
#if gadget.state == "minimized": # starts max, change to min it
|
||||
# self.columns[pos].pack_start(gadget.mainframe, expand=False)
|
||||
#else:
|
||||
self.columns[pos].pack_start(gadget.mainframe, expand=gadget.expand)
|
||||
# set height on gadget.scrolledwindow here:
|
||||
gadget.scrolledwindow.set_size_request(-1, gadget.height)
|
||||
# GTK BUG: can't minimize:
|
||||
#if gadget.state == "minimized": # starts max, change to min it
|
||||
#gadget.set_state("minimized") # minimize it
|
||||
cnt += 1
|
||||
return frame
|
||||
|
||||
|
@ -31,7 +31,7 @@ register(type="gadget", # case in-senstitive keyword "gadget"
|
||||
# There are a number of arguments that you can provide, including:
|
||||
# name, height, content, title, expand, state
|
||||
|
||||
# Hereare a couple of other examples, with their register lines at the
|
||||
# Here are a couple of other examples, with their register lines at the
|
||||
# bottom:
|
||||
|
||||
def make_family_content(gui):
|
||||
@ -40,39 +40,37 @@ def make_family_content(gui):
|
||||
def make_event_content(gui):
|
||||
gui.set_text("Events:")
|
||||
|
||||
# Here is a Gadget object. It has a number of methods possibilities:
|
||||
# Here is a Gadget object. It has a number of method possibilities:
|
||||
# init- run once, on construction
|
||||
# db_changed- run when db-changed is triggered
|
||||
# main- run once per db, main process (for fast code)
|
||||
# background- run once per db, main process (for slow code)
|
||||
# active_changed- run when active-changed is triggered
|
||||
# db_changed- run when db-changed is triggered
|
||||
# main- run once per db change, main process (for fast code)
|
||||
# background- run once per db change, main process (for slow code)
|
||||
|
||||
# You can also call update to run main and background
|
||||
# You can also call update() to run main and background
|
||||
|
||||
class LogGadget(Gadget):
|
||||
def db_changed(self):
|
||||
self.dbstate.connect('person-add', self.log_person_add)
|
||||
self.dbstate.connect('person-delete', self.log_person_delete)
|
||||
self.dbstate.connect('person-update', self.log_person_update)
|
||||
self.dbstate.connect('family-add', self.log_family_add)
|
||||
self.dbstate.connect('family-delete', self.log_family_delete)
|
||||
self.dbstate.connect('family-update', self.log_family_update)
|
||||
self.dbstate.db.connect('person-add', self.log_person_add)
|
||||
self.dbstate.db.connect('person-delete', self.log_person_delete)
|
||||
self.dbstate.db.connect('person-update', self.log_person_update)
|
||||
self.dbstate.db.connect('family-add', self.log_family_add)
|
||||
self.dbstate.db.connect('family-delete', self.log_family_delete)
|
||||
self.dbstate.db.connect('family-update', self.log_family_update)
|
||||
|
||||
def active_changed(self, handle):
|
||||
self.log_active_changed(handle)
|
||||
|
||||
def init(self):
|
||||
self.set_text("Log for this Session\n--------------------\n")
|
||||
self.history = {}
|
||||
|
||||
def log_person_add(self, handles):
|
||||
self.append_text("person-add: ")
|
||||
self.get_person(handles)
|
||||
self.get_person(handles, "person-add")
|
||||
def log_person_delete(self, handles):
|
||||
self.append_text("person-delete: ")
|
||||
self.get_person(handles)
|
||||
self.get_person(handles, "person-delete")
|
||||
def log_person_update(self, handles):
|
||||
self.append_text("person-update: ")
|
||||
self.get_person(handles)
|
||||
self.get_person(handles, "person-update")
|
||||
def log_family_add(self, handles):
|
||||
self.append_text("family-add: %s" % handles)
|
||||
def log_family_delete(self, handles):
|
||||
@ -80,28 +78,30 @@ class LogGadget(Gadget):
|
||||
def log_family_update(self, handles):
|
||||
self.append_text("family-update: %s" % handles)
|
||||
def log_active_changed(self, handles):
|
||||
self.append_text("active-changed: ")
|
||||
self.get_person([handles])
|
||||
self.get_person([handles], "active-changed")
|
||||
|
||||
def get_person(self, handles):
|
||||
def get_person(self, handles, ltype):
|
||||
for person_handle in handles:
|
||||
person = self.dbstate.get_person_from_handle(person_handle)
|
||||
if person:
|
||||
self.append_text(name_displayer.display(person))
|
||||
else:
|
||||
self.append_text(person_handle)
|
||||
self.append_text("\n")
|
||||
if ltype + ": " + person_handle not in self.history:
|
||||
self.append_text("%s: " % ltype)
|
||||
self.history[ltype + ": " + person_handle] = 1
|
||||
person = self.dbstate.db.get_person_from_handle(person_handle)
|
||||
if person:
|
||||
self.link(name_displayer.display(person), person_handle)
|
||||
else:
|
||||
self.link("Unknown", person_handle)
|
||||
self.append_text("\n")
|
||||
|
||||
class TopSurnamesGadget(Gadget):
|
||||
def main(self):
|
||||
self.set_text("Processing...\n")
|
||||
|
||||
def background(self):
|
||||
people = self.dbstate.get_person_handles(sort_handles=False)
|
||||
people = self.dbstate.db.get_person_handles(sort_handles=False)
|
||||
surnames = {}
|
||||
cnt = 0
|
||||
for person_handle in people:
|
||||
person = self.dbstate.get_person_from_handle(person_handle)
|
||||
person = self.dbstate.db.get_person_from_handle(person_handle)
|
||||
if person:
|
||||
surname = person.get_primary_name().get_surname().strip()
|
||||
surnames[surname] = surnames.get(surname, 0) + 1
|
||||
@ -134,14 +134,14 @@ class TopSurnamesGadget(Gadget):
|
||||
|
||||
class StatsGadget(Gadget):
|
||||
def db_changed(self):
|
||||
self.dbstate.connect('person-add', self.update)
|
||||
self.dbstate.connect('person-delete', self.update)
|
||||
self.dbstate.connect('family-add', self.update)
|
||||
self.dbstate.connect('family-delete', self.update)
|
||||
self.dbstate.db.connect('person-add', self.update)
|
||||
self.dbstate.db.connect('person-delete', self.update)
|
||||
self.dbstate.db.connect('family-add', self.update)
|
||||
self.dbstate.db.connect('family-delete', self.update)
|
||||
|
||||
def background(self):
|
||||
self.set_text("Processing...")
|
||||
database = self.dbstate
|
||||
database = self.dbstate.db
|
||||
personList = database.get_person_handles(sort_handles=False)
|
||||
familyList = database.get_family_handles()
|
||||
|
||||
@ -345,6 +345,13 @@ class PythonGadget(Gadget):
|
||||
return True
|
||||
return False
|
||||
|
||||
class TODOGadget(Gadget):
|
||||
def init(self):
|
||||
# GUI setup:
|
||||
self.gui.textview.set_editable(True)
|
||||
self.append_text("> ")
|
||||
|
||||
|
||||
register(type="gadget",
|
||||
name="Families Gadget",
|
||||
height=300,
|
||||
@ -363,7 +370,7 @@ register(type="gadget",
|
||||
name="Top Surnames Gadget",
|
||||
height=230,
|
||||
content = TopSurnamesGadget,
|
||||
title="Top 10 Surnames",
|
||||
title="Top Surnames",
|
||||
)
|
||||
|
||||
register(type="gadget",
|
||||
@ -394,3 +401,10 @@ register(type="gadget",
|
||||
title="Python",
|
||||
)
|
||||
|
||||
register(type="gadget",
|
||||
name="TODO Gadget",
|
||||
height=300,
|
||||
content = TODOGadget,
|
||||
title="TODO List",
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user