New GtkCombo drop down that dynamically changes the pop down strings

svn: r770
This commit is contained in:
Don Allingham 2002-02-12 22:46:39 +00:00
parent b0bc359f38
commit bfb8e54efa
7 changed files with 301 additions and 134 deletions

View File

@ -28,19 +28,16 @@ import gtk
cnv = string.lower cnv = string.lower
class AutoComp: class AutoCompBase:
"""
Allows allow completion of the GtkEntry widget with the entries
in the passed string list.
"""
def __init__(self,widget,plist,source=None): def __init__(self,widget,plist,source=None):
self.entry = widget
if source: if source:
self.nlist = source.nlist self.nlist = source.nlist
else: else:
self.nlist = map((lambda n: (cnv(n),n)),plist) self.nlist = map((lambda n: (cnv(n),n)),plist)
self.nlist.sort() self.nlist.sort()
self.entry.connect("insert-text",self.insert_text) self.nl = "xzsdkdjecsc"
self.l = 0
def insert_text(self,entry,new_text,new_text_len,i_dont_care): def insert_text(self,entry,new_text,new_text_len,i_dont_care):
""" """
@ -76,6 +73,94 @@ class AutoComp:
""" """
entry.select_region(0, 0) entry.select_region(0, 0)
class AutoCombo(AutoCompBase):
"""
Allows allow completion of the GtkEntry widget with the entries
in the passed string list.
"""
def __init__(self,widget,plist,source=None):
AutoCompBase.__init__(self,widget,plist,source)
self.entry = widget
widget.entry.connect("insert-text",self.insert_text)
widget.children()[1].connect("button-press-event",self.build_list)
widget.children()[1].connect("button-release-event",self.setval)
self.vals = [""]
self.inb = 0
def setval(self,widget,event):
self.inb = 0
text = self.entry.entry.get_text()
if self.nl == string.lower(text):
self.entry.entry.set_position(self.l)
self.entry.entry.select_region(self.l, -1)
def build_list(self,widget,event):
self.inb = 1
if self.vals[0] == "":
self.entry.set_popdown_strings([self.entry.entry.get_text()])
else:
self.entry.set_popdown_strings(self.vals)
def timer_callback(self,entry):
"""
The workhors
e routine of file completion. This routine grabs the
current text of the entry box, and grubs through the list item
looking for any case insensitive matches. This routine relies on
public knowledge of the GtkEntry data structure, not on any private
data.
"""
# Clear any timer
timer = entry.get_data("timer");
if (timer):
gtk.timeout_remove(timer)
if self.inb == 1:
return
# Get the user's text
typed = entry.get_text()
if (not typed):
return
typed_lc = string.lower(typed)
if typed_lc == self.nl:
return
self.l = len(typed_lc)
self.vals = []
# Walk the GtkList in the entry box
for nl,n in self.nlist:
# If typed text is a substring of the label text, then fill in
# the entry field with the full text (and correcting
# capitalization), and then select all the characters that
# don't match. With the user's next keystroke these will be
# replaced if they are incorrect.
if nl[0:self.l] == typed_lc:
self.vals.append(n)
if len(self.vals) > 0:
n = self.vals[0]
self.nl = string.lower(n)
entry.set_text(n)
entry.set_position(self.l)
entry.select_region(self.l, -1)
else:
self.vals = [""]
class AutoEntry(AutoCompBase):
"""
Allows allow completion of the GtkEntry widget with the entries
in the passed string list.
"""
def __init__(self,widget,plist,source=None):
AutoCompBase.__init__(self,widget,plist,source)
self.entry = widget
self.entry.connect("insert-text",self.insert_text)
def timer_callback(self,entry): def timer_callback(self,entry):
""" """
The workhorse routine of file completion. This routine grabs the The workhorse routine of file completion. This routine grabs the
@ -84,7 +169,6 @@ class AutoComp:
public knowledge of the GtkEntry data structure, not on any private public knowledge of the GtkEntry data structure, not on any private
data. data.
""" """
# Clear any timer # Clear any timer
timer = entry.get_data("timer"); timer = entry.get_data("timer");
if (timer): if (timer):
@ -96,23 +180,22 @@ class AutoComp:
return return
typed_lc = string.lower(typed) typed_lc = string.lower(typed)
if typed_lc == self.nl:
return
self.l = len(typed_lc)
# Walk the GtkList in the entry box # Walk the GtkList in the entry box
for nl,n in self.nlist: for nl,n in self.nlist:
if (not nl):
continue
# If equal, no need to add any text
if (typed_lc == nl):
return
# If typed text is a substring of the label text, then fill in # If typed text is a substring of the label text, then fill in
# the entry field with the full text (and correcting # the entry field with the full text (and correcting
# capitalization), and then select all the characters that # capitalization), and then select all the characters that
# don't match. With the user's enxt keystroke these will be # don't match. With the user's next keystroke these will be
# replaced if they are incorrect. # replaced if they are incorrect.
if (string.find(nl,typed_lc) == 0): if nl[0:self.l] == typed_lc:
self.nl = nl
entry.set_text(n) entry.set_text(n)
entry.set_position(len(typed)) entry.set_position(self.l)
entry.select_region(len(typed), -1) entry.select_region(self.l, -1)
return return

View File

@ -342,13 +342,14 @@
</widget> </widget>
<widget> <widget>
<class>GtkEntry</class> <class>GtkCombo</class>
<name>birthPlace</name> <name>bpcombo</name>
<can_focus>True</can_focus> <value_in_list>False</value_in_list>
<editable>True</editable> <ok_if_empty>True</ok_if_empty>
<text_visible>True</text_visible> <case_sensitive>False</case_sensitive>
<text_max_length>0</text_max_length> <use_arrows>True</use_arrows>
<text></text> <use_arrows_always>False</use_arrows_always>
<items></items>
<child> <child>
<left_attach>2</left_attach> <left_attach>2</left_attach>
<right_attach>3</right_attach> <right_attach>3</right_attach>
@ -363,6 +364,17 @@
<xfill>True</xfill> <xfill>True</xfill>
<yfill>False</yfill> <yfill>False</yfill>
</child> </child>
<widget>
<class>GtkEntry</class>
<child_name>GtkCombo:entry</child_name>
<name>birthPlace</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
</widget>
</widget> </widget>
</widget> </widget>
</widget> </widget>
@ -557,13 +569,14 @@
</widget> </widget>
<widget> <widget>
<class>GtkEntry</class> <class>GtkCombo</class>
<name>deathPlace</name> <name>dbcombo</name>
<can_focus>True</can_focus> <value_in_list>False</value_in_list>
<editable>True</editable> <ok_if_empty>True</ok_if_empty>
<text_visible>True</text_visible> <case_sensitive>False</case_sensitive>
<text_max_length>0</text_max_length> <use_arrows>True</use_arrows>
<text></text> <use_arrows_always>False</use_arrows_always>
<items></items>
<child> <child>
<left_attach>2</left_attach> <left_attach>2</left_attach>
<right_attach>3</right_attach> <right_attach>3</right_attach>
@ -578,6 +591,17 @@
<xfill>True</xfill> <xfill>True</xfill>
<yfill>False</yfill> <yfill>False</yfill>
</child> </child>
<widget>
<class>GtkEntry</class>
<child_name>GtkCombo:entry</child_name>
<name>deathPlace</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
</widget>
</widget> </widget>
</widget> </widget>
</widget> </widget>
@ -790,54 +814,6 @@
</child> </child>
</widget> </widget>
<widget>
<class>GtkEntry</class>
<name>suffix</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
<child>
<left_attach>1</left_attach>
<right_attach>2</right_attach>
<top_attach>2</top_attach>
<bottom_attach>3</bottom_attach>
<xpad>5</xpad>
<ypad>5</ypad>
<xexpand>True</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
<yfill>False</yfill>
</child>
</widget>
<widget>
<class>GtkEntry</class>
<name>title</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
<child>
<left_attach>1</left_attach>
<right_attach>2</right_attach>
<top_attach>3</top_attach>
<bottom_attach>4</bottom_attach>
<xpad>5</xpad>
<ypad>5</ypad>
<xexpand>True</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
<yfill>False</yfill>
</child>
</widget>
<widget> <widget>
<class>GtkLabel</class> <class>GtkLabel</class>
<name>label22</name> <name>label22</name>
@ -864,6 +840,30 @@
</child> </child>
</widget> </widget>
<widget>
<class>GtkEntry</class>
<name>nickname</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
<child>
<left_attach>1</left_attach>
<right_attach>3</right_attach>
<top_attach>4</top_attach>
<bottom_attach>5</bottom_attach>
<xpad>3</xpad>
<ypad>3</ypad>
<xexpand>True</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
<yfill>False</yfill>
</child>
</widget>
<widget> <widget>
<class>GtkEntry</class> <class>GtkEntry</class>
<name>givenName</name> <name>givenName</name>
@ -878,8 +878,8 @@
<right_attach>3</right_attach> <right_attach>3</right_attach>
<top_attach>0</top_attach> <top_attach>0</top_attach>
<bottom_attach>1</bottom_attach> <bottom_attach>1</bottom_attach>
<xpad>5</xpad> <xpad>3</xpad>
<ypad>5</ypad> <ypad>3</ypad>
<xexpand>True</xexpand> <xexpand>True</xexpand>
<yexpand>False</yexpand> <yexpand>False</yexpand>
<xshrink>False</xshrink> <xshrink>False</xshrink>
@ -889,9 +889,45 @@
</child> </child>
</widget> </widget>
<widget>
<class>GtkCombo</class>
<name>sncombo</name>
<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>
<left_attach>1</left_attach>
<right_attach>3</right_attach>
<top_attach>1</top_attach>
<bottom_attach>2</bottom_attach>
<xpad>3</xpad>
<ypad>3</ypad>
<xexpand>True</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
<yfill>False</yfill>
</child>
<widget>
<class>GtkEntry</class>
<child_name>GtkCombo:entry</child_name>
<name>surname</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
</widget>
</widget>
<widget> <widget>
<class>GtkEntry</class> <class>GtkEntry</class>
<name>nickname</name> <name>suffix</name>
<can_focus>True</can_focus> <can_focus>True</can_focus>
<editable>True</editable> <editable>True</editable>
<text_visible>True</text_visible> <text_visible>True</text_visible>
@ -899,11 +935,11 @@
<text></text> <text></text>
<child> <child>
<left_attach>1</left_attach> <left_attach>1</left_attach>
<right_attach>3</right_attach> <right_attach>2</right_attach>
<top_attach>4</top_attach> <top_attach>2</top_attach>
<bottom_attach>5</bottom_attach> <bottom_attach>3</bottom_attach>
<xpad>5</xpad> <xpad>3</xpad>
<ypad>5</ypad> <ypad>3</ypad>
<xexpand>True</xexpand> <xexpand>True</xexpand>
<yexpand>False</yexpand> <yexpand>False</yexpand>
<xshrink>False</xshrink> <xshrink>False</xshrink>
@ -931,8 +967,8 @@
<right_attach>3</right_attach> <right_attach>3</right_attach>
<top_attach>2</top_attach> <top_attach>2</top_attach>
<bottom_attach>3</bottom_attach> <bottom_attach>3</bottom_attach>
<xpad>5</xpad> <xpad>3</xpad>
<ypad>0</ypad> <ypad>3</ypad>
<xexpand>False</xexpand> <xexpand>False</xexpand>
<yexpand>False</yexpand> <yexpand>False</yexpand>
<xshrink>False</xshrink> <xshrink>False</xshrink>
@ -942,6 +978,30 @@
</child> </child>
</widget> </widget>
<widget>
<class>GtkEntry</class>
<name>title</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
<child>
<left_attach>1</left_attach>
<right_attach>2</right_attach>
<top_attach>3</top_attach>
<bottom_attach>4</bottom_attach>
<xpad>3</xpad>
<ypad>3</ypad>
<xexpand>True</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
<yfill>False</yfill>
</child>
</widget>
<widget> <widget>
<class>GtkButton</class> <class>GtkButton</class>
<name>button106</name> <name>button106</name>
@ -960,8 +1020,8 @@
<right_attach>3</right_attach> <right_attach>3</right_attach>
<top_attach>3</top_attach> <top_attach>3</top_attach>
<bottom_attach>4</bottom_attach> <bottom_attach>4</bottom_attach>
<xpad>5</xpad> <xpad>3</xpad>
<ypad>0</ypad> <ypad>3</ypad>
<xexpand>False</xexpand> <xexpand>False</xexpand>
<yexpand>False</yexpand> <yexpand>False</yexpand>
<xshrink>False</xshrink> <xshrink>False</xshrink>
@ -970,30 +1030,6 @@
<yfill>False</yfill> <yfill>False</yfill>
</child> </child>
</widget> </widget>
<widget>
<class>GtkEntry</class>
<name>surname</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
<child>
<left_attach>1</left_attach>
<right_attach>3</right_attach>
<top_attach>1</top_attach>
<bottom_attach>2</bottom_attach>
<xpad>5</xpad>
<ypad>5</ypad>
<xexpand>True</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
<yfill>False</yfill>
</child>
</widget>
</widget> </widget>
</widget> </widget>
@ -1197,8 +1233,8 @@
<right_attach>3</right_attach> <right_attach>3</right_attach>
<top_attach>0</top_attach> <top_attach>0</top_attach>
<bottom_attach>1</bottom_attach> <bottom_attach>1</bottom_attach>
<xpad>2</xpad> <xpad>3</xpad>
<ypad>0</ypad> <ypad>3</ypad>
<xexpand>True</xexpand> <xexpand>True</xexpand>
<yexpand>False</yexpand> <yexpand>False</yexpand>
<xshrink>False</xshrink> <xshrink>False</xshrink>

View File

@ -181,6 +181,9 @@ class EditPerson:
self.title = self.get_widget("title") self.title = self.get_widget("title")
self.bdate = self.get_widget("birthDate") self.bdate = self.get_widget("birthDate")
self.bplace = self.get_widget("birthPlace") self.bplace = self.get_widget("birthPlace")
self.bpcombo = self.get_widget("bpcombo")
self.dpcombo = self.get_widget("bpcombo")
self.sncombo = self.get_widget("sncombo")
self.ddate = self.get_widget("deathDate") self.ddate = self.get_widget("deathDate")
self.dplace = self.get_widget("deathPlace") self.dplace = self.get_widget("deathPlace")
self.is_male = self.get_widget("genderMale") self.is_male = self.get_widget("genderMale")
@ -216,10 +219,10 @@ class EditPerson:
self.window.editable_enters(self.ddate); self.window.editable_enters(self.ddate);
self.window.editable_enters(self.dplace); self.window.editable_enters(self.dplace);
self.autoplace = AutoComp.AutoComp(self.bplace,self.pmap.keys()) self.autoplace = AutoComp.AutoCombo(self.bpcombo,self.pmap.keys())
AutoComp.AutoComp(self.dplace,self.pmap.keys(),self.autoplace)
if Config.autocomp: AutoComp.AutoCombo(self.dpcombo,self.pmap.keys(),self.autoplace)
self.comp = AutoComp.AutoComp(self.surname_field,const.surnames) self.comp = AutoComp.AutoCombo(self.sncombo,const.surnames)
self.gid.set_text(person.getId()) self.gid.set_text(person.getId())
self.gid.set_editable(Config.id_edit) self.gid.set_editable(Config.id_edit)
@ -318,7 +321,7 @@ class EditPerson:
stat = 0 stat = 0
combo.entry.set_text("") combo.entry.set_text("")
AutoComp.AutoComp(place,None,self.autoplace) AutoComp.AutoEntry(place,None,self.autoplace)
if ord and ord.getPlace(): if ord and ord.getPlace():
place.set_text(ord.getPlace().get_title()) place.set_text(ord.getPlace().get_title())
return stat return stat

View File

@ -100,7 +100,7 @@ class EventEditor:
self.window.editable_enters(self.cause_field); self.window.editable_enters(self.cause_field);
self.window.editable_enters(self.descr_field); self.window.editable_enters(self.descr_field);
AutoComp.AutoComp(self.place_field,self.pmap.keys()) AutoComp.AutoEntry(self.place_field,self.pmap.keys())
if event != None: if event != None:
self.name_field.set_text(event.getName()) self.name_field.set_text(event.getName())

View File

@ -58,7 +58,7 @@ class Find:
self.nlist.append(n.getPrimaryName().getName()) self.nlist.append(n.getPrimaryName().getName())
if Config.autocomp: if Config.autocomp:
self.comp = AutoComp.AutoComp(self.entry,self.nlist) self.comp = AutoComp.AutoEntry(self.entry,self.nlist)
self.next = self.xml.get_widget("next") self.next = self.xml.get_widget("next")
self.top.editable_enters(self.entry) self.top.editable_enters(self.entry)

View File

@ -243,7 +243,7 @@ class NewChild:
self.surname = self.xml.get_widget("surname") self.surname = self.xml.get_widget("surname")
self.given = self.xml.get_widget("childGiven") self.given = self.xml.get_widget("childGiven")
if Config.autocomp: if Config.autocomp:
self.comp = AutoComp.AutoComp(self.surname,const.surnames) self.comp = AutoComp.AutoEntry(self.surname,const.surnames)
self.surname.set_text(self.update_surname(2)) self.surname.set_text(self.update_surname(2))

View File

@ -290,17 +290,25 @@ class GedcomParser:
def parse_source(self,name,level): def parse_source(self,name,level):
self.source = self.db.findSource(name,self.smap) self.source = self.db.findSource(name,self.smap)
note = ""
while 1: while 1:
matches = self.get_next() matches = self.get_next()
if int(matches[0]) < level: if int(matches[0]) < level:
if note:
self.source.setNote(note)
if not self.source.getTitle():
self.source.setTitle("No title - ID %s" % self.source.getId())
self.backup() self.backup()
return return
elif matches[1] == "DATA" or matches[1] == "TEXT":
self.ignore_sub_junk(2)
elif matches[1] == "TITL": elif matches[1] == "TITL":
title = matches[2] + self.parse_continue_data(level+1) title = matches[2] + self.parse_continue_data(level+1)
title = string.replace(title,'\n',' ') title = string.replace(title,'\n',' ')
self.source.setTitle(title) self.source.setTitle(title)
elif matches[1] == "TAXT" or matches[1] == "PERI": # EasyTree Sierra On-Line
if self.source.getTitle() == "":
title = matches[2] + self.parse_continue_data(level+1)
title = string.replace(title,'\n',' ')
self.source.setTitle(title)
elif matches[1] == "AUTH": elif matches[1] == "AUTH":
self.source.setAuthor(matches[2] + self.parse_continue_data(level+1)) self.source.setAuthor(matches[2] + self.parse_continue_data(level+1))
elif matches[1] == "PUBL": elif matches[1] == "PUBL":
@ -309,8 +317,10 @@ class GedcomParser:
self.ignore_sub_junk(2) self.ignore_sub_junk(2)
elif matches[1] == "NOTE": elif matches[1] == "NOTE":
if matches[2] and matches[2][0] != "@": if matches[2] and matches[2][0] != "@":
note = matches[2] + self.parse_continue_data(level+1) if note:
self.source.setNote(note) note = "%s\n%s%s" % (note,matches[2],self.parse_continue_data(level+1))
else:
note = matches[2] + self.parse_continue_data(level+1)
self.ignore_sub_junk(2) self.ignore_sub_junk(2)
else: else:
if self.nmap.has_key(matches[2]): if self.nmap.has_key(matches[2]):
@ -319,6 +329,20 @@ class GedcomParser:
noteobj = Note() noteobj = Note()
self.nmap[matches[2]] = noteobj self.nmap[matches[2]] = noteobj
self.source.setNoteObj(noteobj) self.source.setNoteObj(noteobj)
elif matches[1] == "TEXT":
d = self.parse_continue_data(level+1)
if note:
note = "%s\n%s %s%s" % (note,matches[1],matches[2],d)
else:
note = "%s %s%s" % (matches[1],matches[2],d)
title = matches[2] + d
title = string.replace(title,'\n',' ')
self.source.setTitle(title)
else:
if note:
note = "%s\n%s %s" % (note,matches[1],matches[2])
else:
note = "%s %s" % (matches[1],matches[2])
def parse_record(self): def parse_record(self):
while 1: while 1:
@ -360,9 +384,9 @@ class GedcomParser:
self.nmap[matches[1]] = noteobj self.nmap[matches[1]] = noteobj
text = matches[2][4:] text = matches[2][4:]
if text == "": if text == "":
noteobj.set(self.parse_continue_data(1)) noteobj.set(self.parse_note_continue(1))
else: else:
noteobj.set(text + self.parse_continue_data(1)) noteobj.set(text + self.parse_note_continue(1))
self.parse_note_data(1) self.parse_note_data(1)
elif matches[2] == "OBJE": elif matches[2] == "OBJE":
self.ignore_sub_junk(1) self.ignore_sub_junk(1)
@ -1538,6 +1562,27 @@ class GedcomParser:
self.backup() self.backup()
return data return data
def parse_note_continue(self,level):
data = ""
while 1:
matches = self.get_next()
if int(matches[0]) < level:
self.backup()
return data
elif matches[1] == "NOTE":
data = "%s\n%s%s" % (data,matches[2],self.parse_continue_data(level+1))
elif matches[1] == "CONC":
if self.broken_conc:
data = "%s %s" % (data,matches[2])
else:
data = "%s%s" % (data,matches[2])
elif matches[1] == "CONT":
data = "%s\n%s" % (data,matches[2])
else:
self.backup()
return data
def parse_date(self,level): def parse_date(self,level):
date = DateStruct() date = DateStruct()
while 1: while 1: