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
class AutoComp:
"""
Allows allow completion of the GtkEntry widget with the entries
in the passed string list.
"""
class AutoCompBase:
def __init__(self,widget,plist,source=None):
self.entry = widget
if source:
self.nlist = source.nlist
else:
self.nlist = map((lambda n: (cnv(n),n)),plist)
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):
"""
@ -76,6 +73,94 @@ class AutoComp:
"""
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):
"""
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
data.
"""
# Clear any timer
timer = entry.get_data("timer");
if (timer):
@ -96,23 +180,22 @@ class AutoComp:
return
typed_lc = string.lower(typed)
# Walk the GtkList in the entry box
for nl,n in self.nlist:
if (not nl):
continue
# If equal, no need to add any text
if (typed_lc == nl):
if typed_lc == self.nl:
return
self.l = len(typed_lc)
# 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 enxt keystroke these will be
# don't match. With the user's next keystroke these will be
# 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_position(len(typed))
entry.select_region(len(typed), -1)
entry.set_position(self.l)
entry.select_region(self.l, -1)
return

View File

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

View File

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

View File

@ -100,7 +100,7 @@ class EventEditor:
self.window.editable_enters(self.cause_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:
self.name_field.set_text(event.getName())

View File

@ -58,7 +58,7 @@ class Find:
self.nlist.append(n.getPrimaryName().getName())
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.top.editable_enters(self.entry)

View File

@ -243,7 +243,7 @@ class NewChild:
self.surname = self.xml.get_widget("surname")
self.given = self.xml.get_widget("childGiven")
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))

View File

@ -290,17 +290,25 @@ class GedcomParser:
def parse_source(self,name,level):
self.source = self.db.findSource(name,self.smap)
note = ""
while 1:
matches = self.get_next()
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()
return
elif matches[1] == "DATA" or matches[1] == "TEXT":
self.ignore_sub_junk(2)
elif matches[1] == "TITL":
title = matches[2] + self.parse_continue_data(level+1)
title = string.replace(title,'\n',' ')
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":
self.source.setAuthor(matches[2] + self.parse_continue_data(level+1))
elif matches[1] == "PUBL":
@ -309,8 +317,10 @@ class GedcomParser:
self.ignore_sub_junk(2)
elif matches[1] == "NOTE":
if matches[2] and matches[2][0] != "@":
if 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.source.setNote(note)
self.ignore_sub_junk(2)
else:
if self.nmap.has_key(matches[2]):
@ -319,6 +329,20 @@ class GedcomParser:
noteobj = Note()
self.nmap[matches[2]] = 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):
while 1:
@ -360,9 +384,9 @@ class GedcomParser:
self.nmap[matches[1]] = noteobj
text = matches[2][4:]
if text == "":
noteobj.set(self.parse_continue_data(1))
noteobj.set(self.parse_note_continue(1))
else:
noteobj.set(text + self.parse_continue_data(1))
noteobj.set(text + self.parse_note_continue(1))
self.parse_note_data(1)
elif matches[2] == "OBJE":
self.ignore_sub_junk(1)
@ -1538,6 +1562,27 @@ class GedcomParser:
self.backup()
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):
date = DateStruct()
while 1: