[postr] Added tag autocomplete (#507242)
- From: Germán Poó Caamaño <gpoo src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [postr] Added tag autocomplete (#507242)
- Date: Mon, 21 Dec 2009 21:24:04 +0000 (UTC)
commit 9c6d50ad4b2da243683a3ceb714cbcfffcf02f56
Author: Francisco Rojas <frojas alumnos utalca cl>
Date: Mon Dec 21 18:22:30 2009 -0300
Added tag autocomplete (#507242)
Use the 200 most popular tags of the user and the 20 hottest
tag of the day to autocomplete the tag field.
Signed-off-by: Germán Póo-Caamaño <gpoo gnome org>
src/TagsEntry.py | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/postr.glade | 23 +----------
src/postr.py | 10 ++++-
3 files changed, 124 insertions(+), 21 deletions(-)
---
diff --git a/src/TagsEntry.py b/src/TagsEntry.py
new file mode 100644
index 0000000..9fa4fd0
--- /dev/null
+++ b/src/TagsEntry.py
@@ -0,0 +1,112 @@
+# Postr, a Flickr Uploader
+#
+# Copyright (C) 2009 Francisco Rojas <frojas alumnos utalca cl>
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
+# St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gtk
+
+_USER_POPULAR_TAGS = 200
+_HOTS_TAGS = 20
+_COL_TAG_NAME = 0
+
+class TagsEntry(gtk.Entry):
+ def __init__(self, flickr):
+ gtk.Entry.__init__(self)
+
+ self.flickr = flickr
+
+ # Create the completion object
+ self.completion = gtk.EntryCompletion()
+ self.completion.set_match_func(self.__match_func, None)
+ self.completion.connect('match-selected', self.on_completion_match)
+
+ # Assign the completion to the entry
+ self.set_completion(self.completion)
+
+ # Use model column _COL_TAG_NAME as the text column
+ self.completion.set_text_column(_COL_TAG_NAME)
+
+ self.completion.set_minimum_key_length(1)
+
+
+ self.completion_model = gtk.ListStore(str)
+
+ self.show_all()
+
+ def on_completion_match(self, completion, model, iter):
+ current_text = self.get_text()
+ # if more than a word has been typed, we throw away the
+ # last one because we want to replace it with the matching word
+ # note: the user may have typed only a part of the entire word
+ # and so this step is necessary
+ if ' ' in current_text:
+ current_text = ' '.join(current_text.split(' ')[:-1])
+ # add the matching word
+ current_text = '%s %s ' % (current_text, model[iter][_COL_TAG_NAME])
+ else:
+ current_text = model[iter][_COL_TAG_NAME] +' '
+
+ # set back the whole text
+ self.set_text(current_text)
+ # move the cursor at the end
+ self.set_position(-1)
+
+ return True
+
+
+ def __match_func(self, completion, key_string, iter, data):
+ model = completion.get_model()
+ # get the completion strings
+ modelstr = model[iter][_COL_TAG_NAME]
+ # check if the user has typed in a space char,
+ # get the last word and check if it matches something
+ if ' ' in key_string:
+ last_word = key_string.split(' ')[-1].strip()
+ if last_word == '':
+ return False
+ else:
+ return modelstr.lower().startswith(last_word.lower())
+ # we have only one word typed
+ return modelstr.lower().startswith(key_string.lower())
+
+ def update(self):
+
+ self.completion_model.clear()
+
+ self.flickr.tags_getListUserPopular(user_id=self.flickr.get_nsid(), \
+ count=_USER_POPULAR_TAGS).addCallbacks(self.create_completion_model,
+ self.twisted_error)
+
+ self.flickr.tags_getHotList(user_id=self.flickr.get_nsid(), count=_HOTS_TAGS)\
+ .addCallbacks(self.create_completion_model, self.twisted_error)
+
+ def create_completion_model(self, rsp):
+ '''
+ Creates a tree model containing the completions.
+ '''
+
+ for tag in rsp.getiterator('tag'):
+ self.completion_model.set(self.completion_model.append(),
+ _COL_TAG_NAME,
+ tag.text)
+
+ self.completion.set_model(self.completion_model)
+
+ def twisted_error(self, failure):
+ #TODO: throw a message in a less invasive way
+ from ErrorDialog import ErrorDialog
+ dialog = ErrorDialog()
+ dialog.set_from_failure(failure)
+ dialog.show_all()
diff --git a/src/postr.glade b/src/postr.glade
index ccf4a7e..c29f42b 100644
--- a/src/postr.glade
+++ b/src/postr.glade
@@ -654,14 +654,15 @@
</packing>
</child>
<child>
- <widget class="GtkEntry" id="tags_entry">
+ <widget class="Custom" id="tags_entry">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
+ <property name="creation_function">tag_entry_new</property>
</widget>
<packing>
<property name="left_attach">1</property>
- <property name="right_attach">2</property>
+ <property name="right_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
@@ -682,24 +683,6 @@
</packing>
</child>
<child>
- <widget class="GtkButton" id="tags_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">...</property>
- <property name="relief">GTK_RELIEF_HALF</property>
- <property name="use_underline">True</property>
- <property name="response_id">0</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
<widget class="GtkLabel" id="set_label">
<property name="visible">True</property>
<property name="xalign">0</property>
diff --git a/src/postr.py b/src/postr.py
index de292f7..afbf28f 100644
--- a/src/postr.py
+++ b/src/postr.py
@@ -262,7 +262,11 @@ class Postr(UniqueApp):
bar = StatusBar.StatusBar(self.flickr)
bar.show()
return bar
-
+ def tag_entry_new(self, *args):
+ import TagsEntry
+ entry = TagsEntry.TagsEntry(self.flickr)
+ return entry
+
def on_message(self, app, command, command_data, startup_id, screen, workspace):
"""Callback from UniqueApp, when a message arrives."""
if command == gtkunique.OPEN:
@@ -299,6 +303,7 @@ class Postr(UniqueApp):
self.set_combo.update()
self.license_combo.update()
self.update_avatar()
+ self.update_tag_list()
def on_statusbar_box_expose(self, widget, event):
"""
@@ -1289,3 +1294,6 @@ class Postr(UniqueApp):
self._set_value_in_model(ImageStore.COL_SAFETY, safety_iter, [index])
self._set_value_in_model(ImageStore.COL_VISIBLE, visible, [index])
+ def update_tag_list(self):
+ self.tags_entry.update()
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]