Improved text, enhanced event comparison to load/save complex filters
svn: r514
This commit is contained in:
		| @@ -47,19 +47,15 @@ class Filter: | ||||
|         self.text = text | ||||
|         self.invert = 0 | ||||
|  | ||||
|     #------------------------------------------------------------------------- | ||||
|     # | ||||
|     # compare | ||||
|     # | ||||
|     #------------------------------------------------------------------------- | ||||
|     def get_text(self): | ||||
|         return self.text | ||||
|  | ||||
|     def get_invert(self): | ||||
|         return self.invert | ||||
|  | ||||
|     def set_invert(self,invert): | ||||
|         self.invert = invert | ||||
|  | ||||
|     #------------------------------------------------------------------------- | ||||
|     # | ||||
|     # compare | ||||
|     # | ||||
|     #------------------------------------------------------------------------- | ||||
|     def compare(self,person): | ||||
|         val = self.match(person) | ||||
|         if self.invert: | ||||
| @@ -67,20 +63,9 @@ class Filter: | ||||
|         else: | ||||
|             return val | ||||
|  | ||||
|     #------------------------------------------------------------------------- | ||||
|     # | ||||
|     # __repr__ - print representation | ||||
|     # | ||||
|     #------------------------------------------------------------------------- | ||||
|     def __repr__(self): | ||||
|     def get_name(self): | ||||
|         return str(self.__class__) | ||||
|  | ||||
|     #------------------------------------------------------------------------- | ||||
|     # | ||||
|     # match - returns true if a match is made.  The base class matches  | ||||
|     # everything.   | ||||
|     # | ||||
|     #------------------------------------------------------------------------- | ||||
|     def match(self,person): | ||||
|         return 1 | ||||
|  | ||||
| @@ -91,12 +76,28 @@ class Filter: | ||||
| #------------------------------------------------------------------------- | ||||
|  | ||||
| _filter_list = [(Filter, _("All people"), 0)] | ||||
| _filter2class = {} | ||||
| _filter2descr = {} | ||||
|  | ||||
| def register_filter(class_name, description=None, qualifier=0): | ||||
|     name = str(class_name) | ||||
|     if description == None: | ||||
|         description = _("No description") | ||||
|     _filter2class[name] = class_name | ||||
|     _filter2descr[name] = description | ||||
|     _filter_list.append((class_name,description,qualifier)) | ||||
|  | ||||
| def get_filter_description(name): | ||||
|     if _filter2descr.has_key(name): | ||||
|         return _filter2descr[name] | ||||
|     else: | ||||
|         return "" | ||||
|  | ||||
| def make_filter_from_name(name,qualifier,invert): | ||||
|     a = _filter2class[name](qualifier) | ||||
|     a.set_invert(invert) | ||||
|     return a | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # load_filters - loads all filters in the specfied directory.  Assumes | ||||
|   | ||||
| @@ -336,6 +336,7 @@ class OpenSpreadSheet(SpreadSheetDoc): | ||||
| 	self.f.write('</style:footer>\n') | ||||
| 	self.f.write('</style:master-page>\n') | ||||
| 	self.f.write('</office:master-styles>\n') | ||||
| 	self.f.write('</office:styles>\n') | ||||
| 	self.f.write('</office:document-styles>\n') | ||||
| 	self.f.close() | ||||
|  | ||||
|   | ||||
| @@ -174,7 +174,7 @@ class TableStyle: | ||||
|         else: | ||||
|             self.width = 0 | ||||
|             self.columns = 0 | ||||
|             self.colwid = [ 0 ] * 10 | ||||
|             self.colwid = [ 0 ] * 100 | ||||
|  | ||||
|     def set_width(self,width): | ||||
|         self.width = width | ||||
|   | ||||
| @@ -37,6 +37,7 @@ class EventAfter(Filter.Filter): | ||||
|     def __init__(self,text): | ||||
|         self.date = Date.Date() | ||||
|         self.date.set(text) | ||||
|         Filter.Filter.__init__(self,text) | ||||
|  | ||||
|     def match(self,p): | ||||
|         for event in p.getEventList() + [p.getBirth(), p.getDeath()]: | ||||
|   | ||||
| @@ -37,6 +37,7 @@ class EventBefore(Filter.Filter): | ||||
|     def __init__(self,text): | ||||
|         self.date = Date.Date() | ||||
|         self.date.set(text) | ||||
|         Filter.Filter.__init__(text) | ||||
|  | ||||
|     def match(self,p): | ||||
|         for event in p.getEventList() + [p.getBirth(), p.getDeath()]: | ||||
|   | ||||
| @@ -414,7 +414,7 @@ | ||||
| 	    <name>help1_menu</name> | ||||
|  | ||||
| 	    <widget> | ||||
| 	      <class>GtkMenuItem</class> | ||||
| 	      <class>GtkPixmapMenuItem</class> | ||||
| 	      <name>contents</name> | ||||
| 	      <signal> | ||||
| 		<name>activate</name> | ||||
| @@ -423,10 +423,11 @@ | ||||
| 	      </signal> | ||||
| 	      <label>_User's Manual</label> | ||||
| 	      <right_justify>False</right_justify> | ||||
| 	      <stock_icon>GNOME_STOCK_MENU_BOOK_RED</stock_icon> | ||||
| 	    </widget> | ||||
|  | ||||
| 	    <widget> | ||||
| 	      <class>GtkMenuItem</class> | ||||
| 	      <class>GtkPixmapMenuItem</class> | ||||
| 	      <name>writing_extensions</name> | ||||
| 	      <signal> | ||||
| 		<name>activate</name> | ||||
| @@ -435,6 +436,7 @@ | ||||
| 	      </signal> | ||||
| 	      <label>_Writing Extensions</label> | ||||
| 	      <right_justify>False</right_justify> | ||||
| 	      <stock_icon>GNOME_STOCK_MENU_BOOK_BLUE</stock_icon> | ||||
| 	    </widget> | ||||
|  | ||||
| 	    <widget> | ||||
|   | ||||
| @@ -159,7 +159,7 @@ def on_merge_activate(obj): | ||||
|     if page == 0: | ||||
|         if len(person_list.selection) != 2: | ||||
|             msg = _("Exactly two people must be selected to perform a merge") | ||||
|             GnomeErrorDialog() | ||||
|             GnomeErrorDialog(msg) | ||||
|         else: | ||||
|             import MergeData | ||||
|             p1 = person_list.get_row_data(person_list.selection[0]) | ||||
| @@ -529,7 +529,7 @@ def on_delete_place_clicked(obj): | ||||
|     if len(obj.selection) == 0: | ||||
|         return | ||||
|     elif len(obj.selection) > 1: | ||||
|         msg = _("Currently, you can only delete on place at a time") | ||||
|         msg = _("Currently, you can only delete one place at a time") | ||||
|         topWindow.error(msg) | ||||
|         return | ||||
|     else: | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
|  | ||||
| #------------------------------------------------------------------------ | ||||
| # | ||||
| #  | ||||
| # Module imports | ||||
| # | ||||
| #------------------------------------------------------------------------ | ||||
| import os | ||||
| @@ -30,6 +30,14 @@ import re | ||||
| import sort | ||||
| import utils | ||||
| import string | ||||
| from gtk import * | ||||
| from gnome.ui import * | ||||
| from libglade import * | ||||
| import ListColors | ||||
| import Filter | ||||
| import const | ||||
| from TextDoc import * | ||||
| from OpenSpreadSheet import * | ||||
| import intl | ||||
|  | ||||
| _ = intl.gettext | ||||
| @@ -39,30 +47,7 @@ _ = intl.gettext | ||||
| #  | ||||
| # | ||||
| #------------------------------------------------------------------------ | ||||
| from gtk import * | ||||
| from gnome.ui import * | ||||
| from libglade import * | ||||
|  | ||||
| #------------------------------------------------------------------------ | ||||
| # | ||||
| #  | ||||
| # | ||||
| #------------------------------------------------------------------------ | ||||
| import ListColors | ||||
| import Filter | ||||
| import const | ||||
| from TextDoc import * | ||||
| from OpenSpreadSheet import * | ||||
|  | ||||
|  | ||||
| #------------------------------------------------------------------------ | ||||
| # | ||||
| #  | ||||
| # | ||||
| #------------------------------------------------------------------------ | ||||
|  | ||||
| OBJECT   = "o" | ||||
| INDEX    = "i" | ||||
| FILTER   = "filter" | ||||
| FUNCTION = "function" | ||||
| QUALIFIER= "qual" | ||||
| @@ -79,11 +64,6 @@ class TableReport: | ||||
|         self.filename = filename | ||||
|         self.doc = doc | ||||
|          | ||||
|     #-------------------------------------------------------------------- | ||||
|     # | ||||
|     #  | ||||
|     # | ||||
|     #-------------------------------------------------------------------- | ||||
|     def initialize(self,cols): | ||||
|  | ||||
|         t = TableStyle() | ||||
| @@ -112,20 +92,10 @@ class TableReport: | ||||
|         self.doc.open(self.filename) | ||||
|         self.doc.start_page("Page 1","mytbl") | ||||
|  | ||||
|     #-------------------------------------------------------------------- | ||||
|     # | ||||
|     #  | ||||
|     # | ||||
|     #-------------------------------------------------------------------- | ||||
|     def finalize(self): | ||||
|         self.doc.end_page() | ||||
|         self.doc.close() | ||||
|          | ||||
|     #-------------------------------------------------------------------- | ||||
|     # | ||||
|     #  | ||||
|     # | ||||
|     #-------------------------------------------------------------------- | ||||
|     def write_table_data(self,data): | ||||
|         length = len(data) | ||||
|  | ||||
| @@ -136,19 +106,9 @@ class TableReport: | ||||
|             self.doc.end_cell() | ||||
|         self.doc.end_row() | ||||
|  | ||||
|     #-------------------------------------------------------------------- | ||||
|     # | ||||
|     #  | ||||
|     # | ||||
|     #-------------------------------------------------------------------- | ||||
|     def set_row(self,val): | ||||
|         self.row = val + 2 | ||||
|          | ||||
|     #-------------------------------------------------------------------- | ||||
|     # | ||||
|     #  | ||||
|     # | ||||
|     #-------------------------------------------------------------------- | ||||
|     def write_table_head(self,data): | ||||
|         length = len(data) | ||||
|         self.prev = 3 | ||||
| @@ -167,24 +127,23 @@ class TableReport: | ||||
| #------------------------------------------------------------------------ | ||||
| class EventComparison: | ||||
|  | ||||
|     #------------------------------------------------------------------------ | ||||
|     # | ||||
|     #  | ||||
|     # | ||||
|     #------------------------------------------------------------------------ | ||||
|     def __init__(self,database): | ||||
|         self.db = database | ||||
|  | ||||
|         base = os.path.dirname(__file__) | ||||
|         self.glade_file = base + os.sep + "eventcmp.glade" | ||||
|         self.qual = 0 | ||||
|  | ||||
|         xml = os.path.expanduser("~/.gramps/eventcmp.xml") | ||||
|         self.interface = ComplexFilterFile(xml) | ||||
|  | ||||
|         self.filterDialog = GladeXML(self.glade_file,"filters") | ||||
|         self.filterDialog.signal_autoconnect({ | ||||
|             "on_add_clicked": on_add_clicked, | ||||
|             "on_delete_clicked":on_delete_clicked, | ||||
|             "on_select_row" : on_select_row, | ||||
|             "on_filter_save_clicked" : on_filter_save_clicked, | ||||
|             "on_apply_clicked":on_apply_clicked, | ||||
|             "on_add_clicked"         : self.on_add_clicked, | ||||
|             "on_delete_clicked"      : self.on_delete_clicked, | ||||
|             "on_filter_save_clicked" : self.on_filter_save_clicked, | ||||
|             "on_filter_load_clicked" : self.on_filter_load_clicked, | ||||
|             "on_apply_clicked"       : self.on_apply_clicked, | ||||
|             "destroy_passed_object"  : utils.destroy_passed_object | ||||
|             }) | ||||
|      | ||||
| @@ -193,51 +152,290 @@ class EventComparison: | ||||
|         self.filter_list_obj = self.filterDialog.get_widget("active_filters") | ||||
|         qualifier = self.filterDialog.get_widget("qualifier") | ||||
|  | ||||
|         self.filter_list_obj.set_data(INDEX,-1) | ||||
|         self.filter_list_obj.set_data(OBJECT,self) | ||||
|  | ||||
|         self.filter_list = [] | ||||
|  | ||||
|         myMenu  = Filter.build_filter_menu(on_filter_name_changed,qualifier) | ||||
|         myMenu  = Filter.build_filter_menu(self.on_filter_name_changed,qualifier) | ||||
|         self.filter_menu.set_menu(myMenu) | ||||
|  | ||||
|         top.set_data(OBJECT,self) | ||||
|         top.show() | ||||
|  | ||||
|     #------------------------------------------------------------------------ | ||||
|     # | ||||
|     #  | ||||
|     # | ||||
|     #------------------------------------------------------------------------ | ||||
|     def display_results(self): | ||||
|     def on_apply_clicked(self,obj): | ||||
|         my_list = [] | ||||
|  | ||||
|         for person in self.db.getPersonMap().values(): | ||||
|             match = 1 | ||||
|             for filter in self.filter_list: | ||||
|                 if not filter.compare(person): | ||||
|                     match = 0 | ||||
|             if match == 1: | ||||
|                     break | ||||
|             else: | ||||
|                 my_list.append(person) | ||||
|  | ||||
|         if len(my_list) == 0: | ||||
|             GnomeWarningDialog("No matches were found") | ||||
|         else: | ||||
|             DisplayChart(my_list) | ||||
|  | ||||
|     def on_delete_clicked(self,obj): | ||||
|         if len(self.filter_list_obj.selection) != 1: | ||||
|             return | ||||
|          | ||||
|         self.topDialog = GladeXML(self.glade_file,"top") | ||||
|         row = self.filter_list_obj.selection[0] | ||||
|         self.filter_list_obj.remove(row) | ||||
|         self.filter_list_obj.unselect_all() | ||||
|         del self.filter_list[row] | ||||
|  | ||||
|     def on_add_clicked(self,obj): | ||||
|  | ||||
|         invert = self.filterDialog.get_widget("invert").get_active() | ||||
|         qwidget = self.filterDialog.get_widget("qualifier") | ||||
|  | ||||
|         if self.qual: | ||||
|             qualifier = qwidget.get_text() | ||||
|         else: | ||||
|             qualifier = "" | ||||
|              | ||||
|         menu = self.filter_menu.get_menu() | ||||
|  | ||||
|         function = menu.get_active().get_data(FUNCTION) | ||||
|         name = menu.get_active().get_data(NAME) | ||||
|  | ||||
|         myfilter = function(qualifier) | ||||
|         myfilter.set_invert(invert) | ||||
|      | ||||
|         self.filter_list.append(myfilter) | ||||
|         if invert: | ||||
|             invert_text = "yes" | ||||
|         else: | ||||
|             invert_text = "no" | ||||
|  | ||||
|         self.filter_list_obj.append([name,qualifier,invert_text]) | ||||
|  | ||||
|     def on_filter_save_clicked(self,obj): | ||||
|         self.load_dialog = GladeXML(self.glade_file,"filter_file") | ||||
|         self.filter_combo = self.load_dialog.get_widget("filter_combo") | ||||
|         self.load_dialog.get_widget("title").set_text("Save complex filter") | ||||
|         names = self.interface.get_filter_names() | ||||
|         if len(names) > 0: | ||||
|             self.filter_combo.set_popdown_strings(names) | ||||
|         self.load_dialog.signal_autoconnect({ | ||||
|             "destroy_passed_object" : utils.destroy_passed_object, | ||||
|             "combo_insert_text"     : utils.combo_insert_text, | ||||
|             "on_load_filter"        : self.on_save_filter, | ||||
|             }) | ||||
|  | ||||
|     def on_filter_load_clicked(self,obj): | ||||
|         self.load_dialog = GladeXML(self.glade_file,"filter_file") | ||||
|         self.filter_combo = self.load_dialog.get_widget("filter_combo") | ||||
|         self.load_dialog.get_widget("title").set_text("Load complex filter") | ||||
|         names = self.interface.get_filter_names() | ||||
|         if len(names) > 0: | ||||
|             self.filter_combo.set_popdown_strings(names) | ||||
|         self.load_dialog.signal_autoconnect({ | ||||
|             "destroy_passed_object" : utils.destroy_passed_object, | ||||
|             "combo_insert_text"     : utils.combo_insert_text, | ||||
|             "on_load_filter"        : self.on_load_filter, | ||||
|             }) | ||||
|  | ||||
|     def on_load_filter(self,obj): | ||||
|         name = self.load_dialog.get_widget("name").get_text() | ||||
|         self.filter_list = self.interface.get_filter(name) | ||||
|         self.filter_list_obj.freeze() | ||||
|         self.filter_list_obj.clear() | ||||
|         for f in self.filter_list: | ||||
|             if f.get_invert(): | ||||
|                 invert = "yes" | ||||
|             else: | ||||
|                 invert = "no" | ||||
|             name = str(f.__class__) | ||||
|             name = Filter.get_filter_description(name) | ||||
|             self.filter_list_obj.append([name,f.get_text(),invert]) | ||||
|         self.filter_list_obj.thaw() | ||||
|         utils.destroy_passed_object(obj) | ||||
|  | ||||
|     def on_save_filter(self,obj): | ||||
|         name = self.load_dialog.get_widget("name").get_text() | ||||
|         self.interface.save_filter(name,self.filter_list) | ||||
|         utils.destroy_passed_object(obj) | ||||
|          | ||||
|     def on_filter_name_changed(self,obj): | ||||
|         self.qual = obj.get_data(QUALIFIER) | ||||
|         obj.get_data(FILTER).set_sensitive(self.qual) | ||||
|  | ||||
|  | ||||
| class ComplexFilterFile: | ||||
|     def __init__(self,name): | ||||
|         self.filters = {} | ||||
|         self.fname = name | ||||
|         f = open(self.fname) | ||||
|         parser = make_parser() | ||||
|         parser.setContentHandler(ComplexFilterParser(self)) | ||||
|         parser.parse(f) | ||||
|         f.close() | ||||
|  | ||||
|     def get_filter_names(self): | ||||
|         return self.filters.keys() | ||||
|  | ||||
|     def get_filter(self,name): | ||||
|         if self.filters.has_key(name): | ||||
|             return self.filters[name] | ||||
|         else: | ||||
|             return [] | ||||
|  | ||||
|     def save_filter(self,name,filter_list): | ||||
|         self.filters[name] = filter_list | ||||
|          | ||||
|         f = open(self.fname,"w") | ||||
|         f.write('<?xml version="1.0" encoding="iso-8859-1"?>\n') | ||||
|         f.write('<filterlist>\n') | ||||
|         for name in self.filters.keys(): | ||||
|             f.write('  <complex_filter name="%s">\n' % name) | ||||
|             for filter in self.filters[name]: | ||||
|                 val = (filter.get_name(),filter.get_text(),filter.get_invert()) | ||||
|                 f.write('    <filter name="%s" text="%s" invert="%d"/>\n' % val) | ||||
|             f.write('  </complex_filter>\n') | ||||
|         f.write('</filterlist>\n') | ||||
|         f.close() | ||||
|  | ||||
| class ComplexFilterParser(handler.ContentHandler): | ||||
|     def __init__(self,parent): | ||||
|         self.parent = parent | ||||
|         self.curfilter = [] | ||||
|         self.curname = "" | ||||
|  | ||||
|     def startElement(self,tag,attrs): | ||||
|         if tag == "complex_filter": | ||||
|             self.curname = attrs['name'] | ||||
|             self.curfilter = [] | ||||
|         elif tag == "filter": | ||||
|             name = attrs['name'] | ||||
|             qual = attrs['text'] | ||||
|             invert = int(attrs['invert']) | ||||
|             f = Filter.make_filter_from_name(name,qual,invert) | ||||
|             self.curfilter.append(f) | ||||
|  | ||||
|     def endElement(self,tag): | ||||
|         if tag == "complex_filter": | ||||
|             self.parent.filters[self.curname] = self.curfilter | ||||
|  | ||||
| #------------------------------------------------------------------------ | ||||
| # | ||||
| #  | ||||
| # | ||||
| #------------------------------------------------------------------------ | ||||
| def runTool(database,person,callback): | ||||
|     EventComparison(database) | ||||
|      | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def by_value(first,second): | ||||
|     return cmp(second[0],first[0]) | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def fix(line): | ||||
|     l = string.strip(line) | ||||
|     l = string.replace(l,'&','&') | ||||
|     l = string.replace(l,'>','>') | ||||
|     l = string.replace(l,'<','<') | ||||
|     return string.replace(l,'"','"') | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| class DisplayChart: | ||||
|     def __init__(self,people_list): | ||||
|         self.my_list = people_list | ||||
|         self.row_data = [] | ||||
|          | ||||
|         base = os.path.dirname(__file__) | ||||
|         self.glade_file = base + os.sep + "eventcmp.glade" | ||||
|  | ||||
|         self.topDialog = GladeXML(self.glade_file,"view") | ||||
|         self.topDialog.signal_autoconnect({ | ||||
|             "on_write_table" : on_write_table, | ||||
|             "on_write_table"        : self.on_write_table, | ||||
|             "destroy_passed_object" : utils.destroy_passed_object | ||||
|             }) | ||||
|  | ||||
|         top = self.topDialog.get_widget("top") | ||||
|         top.set_data(OBJECT,self) | ||||
|         table = self.topDialog.get_widget("addarea") | ||||
|         self.top = self.topDialog.get_widget("view") | ||||
|         self.table = self.topDialog.get_widget("addarea") | ||||
|      | ||||
|         my_list.sort(sort.by_last_name) | ||||
|         self.my_list.sort(sort.by_last_name) | ||||
|  | ||||
|         self.event_titles = self.make_event_titles() | ||||
|         self.build_row_data() | ||||
|         self.draw_clist_display() | ||||
|         self.top.show() | ||||
|  | ||||
|     def draw_clist_display(self): | ||||
|  | ||||
|         eventlist = GtkCList(len(self.event_titles),self.event_titles) | ||||
|         self.table.add(eventlist) | ||||
|         eventlist.show() | ||||
|         color_clist = ListColors.ColorList(eventlist,2) | ||||
|  | ||||
|         for (top,bottom) in self.row_data: | ||||
|             color_clist.add(top) | ||||
|             color_clist.add(bottom) | ||||
|  | ||||
|         for index in range(0,len(self.event_titles)): | ||||
|             width = min(150,eventlist.optimal_column_width(index)) | ||||
|             eventlist.set_column_width(index,width) | ||||
|  | ||||
|     def build_row_data(self): | ||||
|         for individual in self.my_list: | ||||
|             name = individual.getPrimaryName().getName() | ||||
|             birth = individual.getBirth() | ||||
|             death = individual.getDeath() | ||||
|             map = {} | ||||
|         for individual in my_list: | ||||
|             elist = individual.getEventList()[:] | ||||
|             for ievent in elist: | ||||
|                 event_name = ievent.getName() | ||||
|                 if map.has_key(event_name): | ||||
|                     map[event_name].append(ievent) | ||||
|                 else: | ||||
|                     map[event_name] = [ievent] | ||||
|  | ||||
|             first = 1 | ||||
|             done = 0 | ||||
|             while done == 0: | ||||
|                 added = 0 | ||||
|                 if first: | ||||
|                     tlist = [name,birth.getDate(),death.getDate()] | ||||
|                     blist = ["",birth.getPlaceName(),death.getPlaceName()] | ||||
|                 else: | ||||
|                     tlist = ["","",""] | ||||
|                     blist = ["","",""] | ||||
|                 for ename in self.event_titles[3:]: | ||||
|                     if map.has_key(ename) and len(map[ename]) > 0: | ||||
|                         event = map[ename][0] | ||||
|                         del map[ename][0] | ||||
|                         tlist.append(event.getDate()) | ||||
|                         blist.append(event.getPlaceName()) | ||||
|                         added = 1 | ||||
|                     else: | ||||
|                         tlist.append("") | ||||
|                         blist.append("") | ||||
|                  | ||||
|                 if first: | ||||
|                     first = 0 | ||||
|                     self.row_data.append((tlist,blist)) | ||||
|                 elif added == 0: | ||||
|                     done = 1 | ||||
|                 else: | ||||
|                     self.row_data.append((tlist,blist)) | ||||
|  | ||||
|     def make_event_titles(self): | ||||
|         """Creates the list of unique event types, along with the person's | ||||
|         name, birth, and death. This should be the column titles of the report""" | ||||
|         map = {} | ||||
|         for individual in self.my_list: | ||||
|             elist = individual.getEventList() | ||||
|             for event in elist: | ||||
|                 name = event.getName() | ||||
| @@ -257,335 +455,42 @@ class EventComparison: | ||||
|         for item in unsort_list: | ||||
|             sort_list.append(item[1]) | ||||
|  | ||||
|         event_titles = ["Person","Birth","Death"] + sort_list | ||||
|         return [_("Person"),_("Birth"),_("Death")] + sort_list | ||||
|  | ||||
|         eventlist = GtkCList(len(event_titles),event_titles) | ||||
|         eventlist.set_data(INDEX,-1) | ||||
|     def on_write_table(self,obj): | ||||
|         self.form = GladeXML(self.glade_file,"dialog1") | ||||
|         self.form.signal_autoconnect({ | ||||
|             "on_save_clicked"       : self.on_save_clicked, | ||||
|             "on_html_toggled"       : self.on_html_toggled, | ||||
|             "destroy_passed_object" : utils.destroy_passed_object | ||||
|             }) | ||||
|         self.save_form = self.form.get_widget("dialog1") | ||||
|         self.save_form.show() | ||||
|  | ||||
|         table.add(eventlist) | ||||
|         eventlist.show() | ||||
|     def on_html_toggled(self,obj): | ||||
|         active = self.form.get_widget("html").get_active() | ||||
|         self.form.get_widget("htmltemplate").set_sensitive(active) | ||||
|  | ||||
|         color_clist = ListColors.ColorList(eventlist,2) | ||||
|      | ||||
|         for individual in my_list: | ||||
|             name = individual.getPrimaryName().getName() | ||||
|             birth = individual.getBirth() | ||||
|             death = individual.getDeath() | ||||
|             map = {} | ||||
|             elist = individual.getEventList()[:] | ||||
|             for ievent in elist: | ||||
|                 event_name = ievent.getName() | ||||
|                 if map.has_key(event_name): | ||||
|                     map[event_name].append(ievent) | ||||
|                 else: | ||||
|                     map[event_name] = [ievent] | ||||
|  | ||||
|             first = 1 | ||||
|             done = 0 | ||||
|             while done == 0: | ||||
|                 added = 0 | ||||
|                 if first: | ||||
|                     tlist = [name,birth.getDate(),death.getDate()] | ||||
|                     blist = ["",birth.getPlaceName(),death.getPlaceName()] | ||||
|                 else: | ||||
|                     tlist = ["","",""] | ||||
|                     blist = ["","",""] | ||||
|                 for ename in event_titles[3:]: | ||||
|                     if map.has_key(ename) and len(map[ename]) > 0: | ||||
|                         mylist = map[ename] | ||||
|                         event = mylist[0] | ||||
|                         del mylist[0] | ||||
|                         tlist.append(event.getDate()) | ||||
|                         blist.append(event.getPlaceName()) | ||||
|                         added = 1 | ||||
|                     else: | ||||
|                         tlist.append("") | ||||
|                         blist.append("") | ||||
|                  | ||||
|                 if first: | ||||
|                     first = 0 | ||||
|                     color_clist.add(tlist) | ||||
|                     color_clist.add(blist) | ||||
|                 elif added == 0: | ||||
|                     done = 1 | ||||
|                 else: | ||||
|                     color_clist.add(tlist) | ||||
|                     color_clist.add(blist) | ||||
|  | ||||
|         for index in range(0,len(event_titles)): | ||||
|             eventlist.set_column_width(index,eventlist.optimal_column_width(index)) | ||||
|         top.show() | ||||
|  | ||||
|     #------------------------------------------------------------------------ | ||||
|     # | ||||
|     #  | ||||
|     # | ||||
|     #------------------------------------------------------------------------ | ||||
|     def save_data(self): | ||||
|          | ||||
|         my_list = [] | ||||
|         for person in self.db.getPersonMap().values(): | ||||
|             match = 1 | ||||
|             for filter in self.filter_list: | ||||
|                 if not filter.compare(person): | ||||
|                     match = 0 | ||||
|             if match == 1: | ||||
|                 my_list.append(person) | ||||
|  | ||||
|         my_list.sort(sort.by_last_name) | ||||
|  | ||||
|         map = {} | ||||
|         for individual in my_list: | ||||
|             elist = individual.getEventList()[:] | ||||
|             for event in elist: | ||||
|                 name = event.getName() | ||||
|                 if not name: | ||||
|                     break | ||||
|                 if map.has_key(name): | ||||
|                     map[name] = map[name] + 1 | ||||
|                 else: | ||||
|                     map[name] = 1 | ||||
|  | ||||
|         unsort_list = [] | ||||
|         for item in map.keys(): | ||||
|             unsort_list.append((map[item],item)) | ||||
|         unsort_list.sort(by_value) | ||||
|  | ||||
|         sort_list = [] | ||||
|         for item in unsort_list: | ||||
|             sort_list.append(item[1]) | ||||
|  | ||||
|         event_titles = ["Person","Birth","Death"] + sort_list | ||||
|     def on_save_clicked(self,obj): | ||||
|          | ||||
|         name = self.form.get_widget("filename").get_text() | ||||
|  | ||||
|         doc = OpenSpreadSheet(PaperStyle("junk",10,10),PAPER_PORTRAIT) | ||||
|         spreadsheet = TableReport(name,doc) | ||||
|         spreadsheet.initialize(len(event_titles)) | ||||
|         spreadsheet.initialize(len(self.event_titles)) | ||||
|  | ||||
|  | ||||
|         spreadsheet.write_table_head(event_titles) | ||||
|         spreadsheet.write_table_head(self.event_titles) | ||||
|  | ||||
|         index = 0 | ||||
|         for individual in my_list: | ||||
|         for (top,bottom) in self.row_data: | ||||
|             spreadsheet.set_row(index%2) | ||||
|             index = index + 1 | ||||
|             name = individual.getPrimaryName().getName() | ||||
|             birth = individual.getBirth() | ||||
|             death = individual.getDeath() | ||||
|             map = {} | ||||
|             elist = individual.getEventList()[:] | ||||
|             for ievent in elist: | ||||
|                 event_name = ievent.getName() | ||||
|                 if map.has_key(event_name): | ||||
|                     map[event_name].append(ievent) | ||||
|                 else: | ||||
|                     map[event_name] = [ievent] | ||||
|  | ||||
|             first = 1 | ||||
|             done = 0 | ||||
|             while done == 0: | ||||
|                 added = 0 | ||||
|                 if first: | ||||
|                     tlist = [name,birth.getDate(),death.getDate()] | ||||
|                     blist = ["",birth.getPlaceName(),death.getPlaceName()] | ||||
|                 else: | ||||
|                     tlist = ["","",""] | ||||
|                     blist = ["","",""] | ||||
|                 for ename in event_titles[3:]: | ||||
|                     if map.has_key(ename) and len(map[ename]) > 0: | ||||
|                         mylist = map[ename] | ||||
|                         event = mylist[0] | ||||
|                         del mylist[0] | ||||
|                         tlist.append(event.getDate()) | ||||
|                         blist.append(event.getPlaceName()) | ||||
|                         added = 1 | ||||
|                     else: | ||||
|                         tlist.append("") | ||||
|                         blist.append("") | ||||
|                  | ||||
|                 if first: | ||||
|                     first = 0 | ||||
|                     spreadsheet.write_table_data(tlist) | ||||
|                     spreadsheet.write_table_data(blist) | ||||
|                 elif added == 0: | ||||
|                     done = 1 | ||||
|                 else: | ||||
|                     spreadsheet.write_table_data(tlist) | ||||
|                     spreadsheet.write_table_data(blist) | ||||
|             spreadsheet.write_table_data(top) | ||||
|             spreadsheet.write_table_data(bottom) | ||||
|  | ||||
|         spreadsheet.finalize() | ||||
|  | ||||
|     #------------------------------------------------------------------------ | ||||
|     # | ||||
|     #  | ||||
|     # | ||||
|     #------------------------------------------------------------------------ | ||||
|     def display_save_form(self): | ||||
|         self.form = GladeXML(self.glade_file,"dialog1") | ||||
|         self.form.signal_autoconnect({ | ||||
|             "on_save_clicked": on_save_clicked, | ||||
|             "on_html_toggled": on_html_toggled, | ||||
|             "destroy_passed_object" : utils.destroy_passed_object | ||||
|             }) | ||||
|         self.save_form = self.form.get_widget("dialog1") | ||||
|         self.save_form.set_data(OBJECT,self) | ||||
|         self.save_form.show() | ||||
|  | ||||
| #------------------------------------------------------------------------ | ||||
| # | ||||
| #  | ||||
| # | ||||
| #------------------------------------------------------------------------ | ||||
| def runTool(database,person,callback): | ||||
|     EventComparison(database) | ||||
|      | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def on_apply_clicked(obj): | ||||
|     myobj = obj.get_data(OBJECT) | ||||
|     myobj.display_results() | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def on_write_table(obj): | ||||
|     myobj = obj.get_data(OBJECT) | ||||
|     myobj.display_save_form() | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def on_save_clicked(obj): | ||||
|     myobj = obj.get_data(OBJECT) | ||||
|     myobj.save_data() | ||||
|         utils.destroy_passed_object(obj) | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def on_html_toggled(obj): | ||||
|     myobj = obj.get_data(OBJECT) | ||||
|     if myobj.form.get_widget("html").get_active(): | ||||
|         myobj.form.get_widget("htmltemplate").set_sensitive(1) | ||||
|     else: | ||||
|         myobj.form.get_widget("htmltemplate").set_sensitive(0) | ||||
|          | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def on_double_click(obj,event): | ||||
|     import EditPerson | ||||
|  | ||||
|     row = obj.get_data(INDEX) | ||||
|     if event.button == 1 and event.type == GDK._2BUTTON_PRESS and row != -1: | ||||
|         EditPerson.EditPerson(obj.get_row_data(row)) | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def on_select_row(obj,row,b,c): | ||||
|     obj.set_data(INDEX,row) | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def on_delete_clicked(obj): | ||||
|     myobj = obj.get_data(OBJECT) | ||||
|     row = myobj.filter_list_obj.get_data(INDEX) | ||||
|  | ||||
|     if row == -1: | ||||
|         return | ||||
|     myobj.filter_list_obj.remove(row) | ||||
|     myobj.filter_list_obj.set_data(INDEX,row-1) | ||||
|     myobj.filter_list_obj.unselect_all() | ||||
|     del myobj.filter_list[row] | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def on_add_clicked(obj): | ||||
|  | ||||
|     myobj = obj.get_data(OBJECT) | ||||
|  | ||||
|     invert = myobj.filterDialog.get_widget("invert").get_active() | ||||
|     qualifier = myobj.filterDialog.get_widget("qualifier").get_text() | ||||
|     menu = myobj.filter_menu.get_menu() | ||||
|  | ||||
|     function = menu.get_active().get_data(FUNCTION) | ||||
|     name = menu.get_active().get_data(NAME) | ||||
|  | ||||
|     myfilter = function(qualifier) | ||||
|     myfilter.set_invert(invert) | ||||
|      | ||||
|     myobj.filter_list.append(myfilter) | ||||
|  | ||||
|     row = myobj.filter_list_obj.get_data(INDEX) | ||||
|  | ||||
|     myobj.filter_list_obj.set_data(INDEX,row+1) | ||||
|     if invert: | ||||
|         invert_text = "yes" | ||||
|     else: | ||||
|         invert_text = "no" | ||||
|  | ||||
|     myobj.filter_list_obj.append([name,qualifier,invert_text]) | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def on_filter_name_changed(obj): | ||||
|     obj.get_data(FILTER).set_sensitive(obj.get_data(QUALIFIER)) | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def by_value(first,second): | ||||
|     return cmp(second[0],first[0]) | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def on_filter_save_clicked(obj): | ||||
|     myobj = obj.get_data(OBJECT) | ||||
|  | ||||
|     for filter in myobj.filter_list: | ||||
|         print "%s(\"%s\"),%d" % (filter,filter.text,filter.invert) | ||||
|          | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| def fix(line): | ||||
|     l = string.strip(line) | ||||
|     l = string.replace(l,'&','&') | ||||
|     l = string.replace(l,'>','>') | ||||
|     l = string.replace(l,'<','<') | ||||
|     return string.replace(l,'"','"') | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
|   | ||||
| @@ -85,16 +85,7 @@ | ||||
| 	    <object>filters</object> | ||||
| 	    <last_modification_time>Tue, 06 Mar 2001 23:40:27 GMT</last_modification_time> | ||||
| 	  </signal> | ||||
| 	  <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> | ||||
| 	  <relief>GTK_RELIEF_NORMAL</relief> | ||||
| 	</widget> | ||||
|  | ||||
| 	<widget> | ||||
| 	  <class>GtkButton</class> | ||||
| 	  <name>button10</name> | ||||
| 	  <can_default>True</can_default> | ||||
| 	  <can_focus>True</can_focus> | ||||
| 	  <stock_button>GNOME_STOCK_BUTTON_HELP</stock_button> | ||||
| 	  <stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button> | ||||
| 	  <relief>GTK_RELIEF_NORMAL</relief> | ||||
| 	</widget> | ||||
|       </widget> | ||||
| @@ -371,6 +362,11 @@ | ||||
| 	  <name>button17</name> | ||||
| 	  <can_default>True</can_default> | ||||
| 	  <can_focus>True</can_focus> | ||||
| 	  <signal> | ||||
| 	    <name>clicked</name> | ||||
| 	    <handler>on_filter_load_clicked</handler> | ||||
| 	    <last_modification_time>Sun, 28 Oct 2001 21:28:30 GMT</last_modification_time> | ||||
| 	  </signal> | ||||
| 	  <label>Load</label> | ||||
| 	  <relief>GTK_RELIEF_NORMAL</relief> | ||||
| 	</widget> | ||||
| @@ -394,139 +390,10 @@ | ||||
|   </widget> | ||||
| </widget> | ||||
|  | ||||
| <widget> | ||||
|   <class>GtkWindow</class> | ||||
|   <name>top</name> | ||||
|   <title>Gramps - Event Comparison</title> | ||||
|   <type>GTK_WINDOW_TOPLEVEL</type> | ||||
|   <position>GTK_WIN_POS_NONE</position> | ||||
|   <modal>False</modal> | ||||
|   <allow_shrink>False</allow_shrink> | ||||
|   <allow_grow>True</allow_grow> | ||||
|   <auto_shrink>False</auto_shrink> | ||||
|  | ||||
|   <widget> | ||||
|     <class>GtkTable</class> | ||||
|     <name>temp</name> | ||||
|     <rows>3</rows> | ||||
|     <columns>1</columns> | ||||
|     <homogeneous>False</homogeneous> | ||||
|     <row_spacing>0</row_spacing> | ||||
|     <column_spacing>0</column_spacing> | ||||
|  | ||||
|     <widget> | ||||
|       <class>GtkHButtonBox</class> | ||||
|       <name>hbuttonbox4</name> | ||||
|       <layout_style>GTK_BUTTONBOX_END</layout_style> | ||||
|       <spacing>30</spacing> | ||||
|       <child_min_width>85</child_min_width> | ||||
|       <child_min_height>27</child_min_height> | ||||
|       <child_ipad_x>7</child_ipad_x> | ||||
|       <child_ipad_y>0</child_ipad_y> | ||||
|       <child> | ||||
| 	<left_attach>0</left_attach> | ||||
| 	<right_attach>1</right_attach> | ||||
| 	<top_attach>2</top_attach> | ||||
| 	<bottom_attach>3</bottom_attach> | ||||
| 	<xpad>0</xpad> | ||||
| 	<ypad>0</ypad> | ||||
| 	<xexpand>True</xexpand> | ||||
| 	<yexpand>False</yexpand> | ||||
| 	<xshrink>False</xshrink> | ||||
| 	<yshrink>False</yshrink> | ||||
| 	<xfill>True</xfill> | ||||
| 	<yfill>True</yfill> | ||||
|       </child> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>GtkButton</class> | ||||
| 	<name>button12</name> | ||||
| 	<can_default>True</can_default> | ||||
| 	<can_focus>True</can_focus> | ||||
| 	<signal> | ||||
| 	  <name>clicked</name> | ||||
| 	  <handler>on_write_table</handler> | ||||
| 	  <object>top</object> | ||||
| 	  <last_modification_time>Thu, 15 Mar 2001 20:53:45 GMT</last_modification_time> | ||||
| 	</signal> | ||||
| 	<label>Save As...</label> | ||||
| 	<relief>GTK_RELIEF_NORMAL</relief> | ||||
|       </widget> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>GtkButton</class> | ||||
| 	<name>button13</name> | ||||
| 	<can_default>True</can_default> | ||||
| 	<can_focus>True</can_focus> | ||||
| 	<signal> | ||||
| 	  <name>clicked</name> | ||||
| 	  <handler>destroy_passed_object</handler> | ||||
| 	  <object>top</object> | ||||
| 	  <last_modification_time>Thu, 08 Mar 2001 16:10:16 GMT</last_modification_time> | ||||
| 	</signal> | ||||
| 	<stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button> | ||||
| 	<relief>GTK_RELIEF_NORMAL</relief> | ||||
|       </widget> | ||||
|     </widget> | ||||
|  | ||||
|     <widget> | ||||
|       <class>GtkLabel</class> | ||||
|       <name>label10</name> | ||||
|       <label>Event Comparison</label> | ||||
|       <justify>GTK_JUSTIFY_CENTER</justify> | ||||
|       <wrap>False</wrap> | ||||
|       <xalign>0.5</xalign> | ||||
|       <yalign>0.5</yalign> | ||||
|       <xpad>0</xpad> | ||||
|       <ypad>0</ypad> | ||||
|       <child> | ||||
| 	<left_attach>0</left_attach> | ||||
| 	<right_attach>1</right_attach> | ||||
| 	<top_attach>0</top_attach> | ||||
| 	<bottom_attach>1</bottom_attach> | ||||
| 	<xpad>0</xpad> | ||||
| 	<ypad>0</ypad> | ||||
| 	<xexpand>False</xexpand> | ||||
| 	<yexpand>False</yexpand> | ||||
| 	<xshrink>False</xshrink> | ||||
| 	<yshrink>False</yshrink> | ||||
| 	<xfill>False</xfill> | ||||
| 	<yfill>False</yfill> | ||||
|       </child> | ||||
|     </widget> | ||||
|  | ||||
|     <widget> | ||||
|       <class>GtkScrolledWindow</class> | ||||
|       <name>addarea</name> | ||||
|       <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy> | ||||
|       <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> | ||||
|       <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> | ||||
|       <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> | ||||
|       <child> | ||||
| 	<left_attach>0</left_attach> | ||||
| 	<right_attach>1</right_attach> | ||||
| 	<top_attach>1</top_attach> | ||||
| 	<bottom_attach>2</bottom_attach> | ||||
| 	<xpad>0</xpad> | ||||
| 	<ypad>0</ypad> | ||||
| 	<xexpand>False</xexpand> | ||||
| 	<yexpand>True</yexpand> | ||||
| 	<xshrink>False</xshrink> | ||||
| 	<yshrink>False</yshrink> | ||||
| 	<xfill>True</xfill> | ||||
| 	<yfill>True</yfill> | ||||
|       </child> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>Placeholder</class> | ||||
|       </widget> | ||||
|     </widget> | ||||
|   </widget> | ||||
| </widget> | ||||
|  | ||||
| <widget> | ||||
|   <class>GnomeDialog</class> | ||||
|   <name>dialog1</name> | ||||
|   <title>Gramps - Save as a Spreadsheet</title> | ||||
|   <type>GTK_WINDOW_DIALOG</type> | ||||
|   <position>GTK_WIN_POS_NONE</position> | ||||
|   <modal>False</modal> | ||||
| @@ -781,4 +648,294 @@ | ||||
|   </widget> | ||||
| </widget> | ||||
|  | ||||
| <widget> | ||||
|   <class>GnomeDialog</class> | ||||
|   <name>view</name> | ||||
|   <height>350</height> | ||||
|   <title>Gramps - Event Comparison</title> | ||||
|   <type>GTK_WINDOW_TOPLEVEL</type> | ||||
|   <position>GTK_WIN_POS_NONE</position> | ||||
|   <modal>False</modal> | ||||
|   <allow_shrink>False</allow_shrink> | ||||
|   <allow_grow>True</allow_grow> | ||||
|   <auto_shrink>False</auto_shrink> | ||||
|   <auto_close>False</auto_close> | ||||
|   <hide_on_close>False</hide_on_close> | ||||
|  | ||||
|   <widget> | ||||
|     <class>GtkVBox</class> | ||||
|     <child_name>GnomeDialog:vbox</child_name> | ||||
|     <name>dialog-vbox3</name> | ||||
|     <homogeneous>False</homogeneous> | ||||
|     <spacing>8</spacing> | ||||
|     <child> | ||||
|       <padding>4</padding> | ||||
|       <expand>True</expand> | ||||
|       <fill>True</fill> | ||||
|     </child> | ||||
|  | ||||
|     <widget> | ||||
|       <class>GtkHButtonBox</class> | ||||
|       <child_name>GnomeDialog:action_area</child_name> | ||||
|       <name>dialog-action_area3</name> | ||||
|       <layout_style>GTK_BUTTONBOX_END</layout_style> | ||||
|       <spacing>8</spacing> | ||||
|       <child_min_width>85</child_min_width> | ||||
|       <child_min_height>27</child_min_height> | ||||
|       <child_ipad_x>7</child_ipad_x> | ||||
|       <child_ipad_y>0</child_ipad_y> | ||||
|       <child> | ||||
| 	<padding>0</padding> | ||||
| 	<expand>False</expand> | ||||
| 	<fill>True</fill> | ||||
| 	<pack>GTK_PACK_END</pack> | ||||
|       </child> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>GtkButton</class> | ||||
| 	<name>button19</name> | ||||
| 	<can_default>True</can_default> | ||||
| 	<can_focus>True</can_focus> | ||||
| 	<signal> | ||||
| 	  <name>clicked</name> | ||||
| 	  <handler>on_write_table</handler> | ||||
| 	  <object>view</object> | ||||
| 	  <last_modification_time>Sun, 28 Oct 2001 15:21:19 GMT</last_modification_time> | ||||
| 	</signal> | ||||
| 	<label>Save As...</label> | ||||
| 	<stock_pixmap>GNOME_STOCK_PIXMAP_SAVE_AS</stock_pixmap> | ||||
|       </widget> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>GtkButton</class> | ||||
| 	<name>button21</name> | ||||
| 	<can_default>True</can_default> | ||||
| 	<can_focus>True</can_focus> | ||||
| 	<signal> | ||||
| 	  <name>clicked</name> | ||||
| 	  <handler>destroy_passed_object</handler> | ||||
| 	  <object>view</object> | ||||
| 	  <last_modification_time>Sun, 28 Oct 2001 15:19:04 GMT</last_modification_time> | ||||
| 	</signal> | ||||
| 	<stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button> | ||||
|       </widget> | ||||
|     </widget> | ||||
|  | ||||
|     <widget> | ||||
|       <class>GtkTable</class> | ||||
|       <name>mytable</name> | ||||
|       <rows>2</rows> | ||||
|       <columns>1</columns> | ||||
|       <homogeneous>False</homogeneous> | ||||
|       <row_spacing>0</row_spacing> | ||||
|       <column_spacing>0</column_spacing> | ||||
|       <child> | ||||
| 	<padding>0</padding> | ||||
| 	<expand>True</expand> | ||||
| 	<fill>True</fill> | ||||
|       </child> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>GtkLabel</class> | ||||
| 	<name>label10</name> | ||||
| 	<width>400</width> | ||||
| 	<label>Event Comparison</label> | ||||
| 	<justify>GTK_JUSTIFY_CENTER</justify> | ||||
| 	<wrap>False</wrap> | ||||
| 	<xalign>0.5</xalign> | ||||
| 	<yalign>0.5</yalign> | ||||
| 	<xpad>0</xpad> | ||||
| 	<ypad>0</ypad> | ||||
| 	<child> | ||||
| 	  <left_attach>0</left_attach> | ||||
| 	  <right_attach>1</right_attach> | ||||
| 	  <top_attach>0</top_attach> | ||||
| 	  <bottom_attach>1</bottom_attach> | ||||
| 	  <xpad>0</xpad> | ||||
| 	  <ypad>10</ypad> | ||||
| 	  <xexpand>False</xexpand> | ||||
| 	  <yexpand>False</yexpand> | ||||
| 	  <xshrink>False</xshrink> | ||||
| 	  <yshrink>False</yshrink> | ||||
| 	  <xfill>True</xfill> | ||||
| 	  <yfill>False</yfill> | ||||
| 	</child> | ||||
|       </widget> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>GtkScrolledWindow</class> | ||||
| 	<name>addarea</name> | ||||
| 	<hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy> | ||||
| 	<vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> | ||||
| 	<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> | ||||
| 	<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> | ||||
| 	<child> | ||||
| 	  <left_attach>0</left_attach> | ||||
| 	  <right_attach>1</right_attach> | ||||
| 	  <top_attach>1</top_attach> | ||||
| 	  <bottom_attach>2</bottom_attach> | ||||
| 	  <xpad>0</xpad> | ||||
| 	  <ypad>0</ypad> | ||||
| 	  <xexpand>True</xexpand> | ||||
| 	  <yexpand>True</yexpand> | ||||
| 	  <xshrink>False</xshrink> | ||||
| 	  <yshrink>False</yshrink> | ||||
| 	  <xfill>True</xfill> | ||||
| 	  <yfill>True</yfill> | ||||
| 	</child> | ||||
|  | ||||
| 	<widget> | ||||
| 	  <class>Placeholder</class> | ||||
| 	</widget> | ||||
|       </widget> | ||||
|     </widget> | ||||
|   </widget> | ||||
| </widget> | ||||
|  | ||||
| <widget> | ||||
|   <class>GnomeDialog</class> | ||||
|   <name>filter_file</name> | ||||
|   <title>Gramps - Complex Filter</title> | ||||
|   <type>GTK_WINDOW_TOPLEVEL</type> | ||||
|   <position>GTK_WIN_POS_NONE</position> | ||||
|   <modal>False</modal> | ||||
|   <allow_shrink>False</allow_shrink> | ||||
|   <allow_grow>True</allow_grow> | ||||
|   <auto_shrink>False</auto_shrink> | ||||
|   <auto_close>False</auto_close> | ||||
|   <hide_on_close>False</hide_on_close> | ||||
|  | ||||
|   <widget> | ||||
|     <class>GtkVBox</class> | ||||
|     <child_name>GnomeDialog:vbox</child_name> | ||||
|     <name>dialog-vbox4</name> | ||||
|     <homogeneous>False</homogeneous> | ||||
|     <spacing>8</spacing> | ||||
|     <child> | ||||
|       <padding>4</padding> | ||||
|       <expand>True</expand> | ||||
|       <fill>True</fill> | ||||
|     </child> | ||||
|  | ||||
|     <widget> | ||||
|       <class>GtkHButtonBox</class> | ||||
|       <child_name>GnomeDialog:action_area</child_name> | ||||
|       <name>dialog-action_area4</name> | ||||
|       <layout_style>GTK_BUTTONBOX_END</layout_style> | ||||
|       <spacing>8</spacing> | ||||
|       <child_min_width>85</child_min_width> | ||||
|       <child_min_height>27</child_min_height> | ||||
|       <child_ipad_x>7</child_ipad_x> | ||||
|       <child_ipad_y>0</child_ipad_y> | ||||
|       <child> | ||||
| 	<padding>0</padding> | ||||
| 	<expand>False</expand> | ||||
| 	<fill>True</fill> | ||||
| 	<pack>GTK_PACK_END</pack> | ||||
|       </child> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>GtkButton</class> | ||||
| 	<name>button22</name> | ||||
| 	<can_default>True</can_default> | ||||
| 	<can_focus>True</can_focus> | ||||
| 	<signal> | ||||
| 	  <name>clicked</name> | ||||
| 	  <handler>on_load_filter</handler> | ||||
| 	  <object>filter_file</object> | ||||
| 	  <last_modification_time>Sun, 28 Oct 2001 22:46:35 GMT</last_modification_time> | ||||
| 	</signal> | ||||
| 	<stock_button>GNOME_STOCK_BUTTON_OK</stock_button> | ||||
|       </widget> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>GtkButton</class> | ||||
| 	<name>button24</name> | ||||
| 	<can_default>True</can_default> | ||||
| 	<can_focus>True</can_focus> | ||||
| 	<signal> | ||||
| 	  <name>clicked</name> | ||||
| 	  <handler>destroy_passed_object</handler> | ||||
| 	  <object>filter_file</object> | ||||
| 	  <last_modification_time>Sun, 28 Oct 2001 22:46:21 GMT</last_modification_time> | ||||
| 	</signal> | ||||
| 	<stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> | ||||
|       </widget> | ||||
|     </widget> | ||||
|  | ||||
|     <widget> | ||||
|       <class>GtkVBox</class> | ||||
|       <name>vbox6</name> | ||||
|       <homogeneous>False</homogeneous> | ||||
|       <spacing>0</spacing> | ||||
|       <child> | ||||
| 	<padding>0</padding> | ||||
| 	<expand>True</expand> | ||||
| 	<fill>True</fill> | ||||
|       </child> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>GtkLabel</class> | ||||
| 	<name>title</name> | ||||
| 	<label>Save complex filter as:</label> | ||||
| 	<justify>GTK_JUSTIFY_CENTER</justify> | ||||
| 	<wrap>False</wrap> | ||||
| 	<xalign>0.5</xalign> | ||||
| 	<yalign>0.5</yalign> | ||||
| 	<xpad>0</xpad> | ||||
| 	<ypad>0</ypad> | ||||
| 	<child> | ||||
| 	  <padding>5</padding> | ||||
| 	  <expand>False</expand> | ||||
| 	  <fill>False</fill> | ||||
| 	</child> | ||||
|       </widget> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>GtkHSeparator</class> | ||||
| 	<name>hseparator2</name> | ||||
| 	<child> | ||||
| 	  <padding>5</padding> | ||||
| 	  <expand>True</expand> | ||||
| 	  <fill>True</fill> | ||||
| 	</child> | ||||
|       </widget> | ||||
|  | ||||
|       <widget> | ||||
| 	<class>GtkCombo</class> | ||||
| 	<name>filter_combo</name> | ||||
| 	<width>350</width> | ||||
| 	<value_in_list>False</value_in_list> | ||||
| 	<ok_if_empty>True</ok_if_empty> | ||||
| 	<case_sensitive>False</case_sensitive> | ||||
| 	<use_arrows>True</use_arrows> | ||||
| 	<use_arrows_always>False</use_arrows_always> | ||||
| 	<items></items> | ||||
| 	<child> | ||||
| 	  <padding>15</padding> | ||||
| 	  <expand>False</expand> | ||||
| 	  <fill>False</fill> | ||||
| 	</child> | ||||
|  | ||||
| 	<widget> | ||||
| 	  <class>GtkEntry</class> | ||||
| 	  <child_name>GtkCombo:entry</child_name> | ||||
| 	  <name>name</name> | ||||
| 	  <can_focus>True</can_focus> | ||||
| 	  <signal> | ||||
| 	    <name>insert_text</name> | ||||
| 	    <handler>combo_insert_text</handler> | ||||
| 	    <object>filter_combo</object> | ||||
| 	    <last_modification_time>Sun, 28 Oct 2001 21:27:05 GMT</last_modification_time> | ||||
| 	  </signal> | ||||
| 	  <editable>True</editable> | ||||
| 	  <text_visible>True</text_visible> | ||||
| 	  <text_max_length>0</text_max_length> | ||||
| 	  <text></text> | ||||
| 	</widget> | ||||
|       </widget> | ||||
|     </widget> | ||||
|   </widget> | ||||
| </widget> | ||||
|  | ||||
| </GTK-Interface> | ||||
|   | ||||
| @@ -265,7 +265,7 @@ | ||||
| 	    <class>GtkLabel</class> | ||||
| 	    <child_name>CList:title</child_name> | ||||
| 	    <name>label57</name> | ||||
| 	    <label>Person #1</label> | ||||
| 	    <label>Person 1</label> | ||||
| 	    <justify>GTK_JUSTIFY_CENTER</justify> | ||||
| 	    <wrap>False</wrap> | ||||
| 	    <xalign>0.5</xalign> | ||||
| @@ -278,7 +278,7 @@ | ||||
| 	    <class>GtkLabel</class> | ||||
| 	    <child_name>CList:title</child_name> | ||||
| 	    <name>label58</name> | ||||
| 	    <label>Person #2</label> | ||||
| 	    <label>Person 2</label> | ||||
| 	    <justify>GTK_JUSTIFY_CENTER</justify> | ||||
| 	    <wrap>False</wrap> | ||||
| 	    <xalign>0.5</xalign> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user