Fixed major issue with db/dbstate

svn: r9580
This commit is contained in:
Doug Blank 2007-12-25 04:34:42 +00:00
parent 5f077e4795
commit fe8a8d4986
2 changed files with 149 additions and 61 deletions

View File

@ -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

View File

@ -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",
)