""" CategorySelector.py
Module for selecting categories
"""
__copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc."
__license__ = """
Straw 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 of the License, or (at your option) any later
version.
Straw 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., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA. """
import locale
import pygtk
pygtk.require('2.0')
import gobject
import gtk
import FeedCategoryList
import MVP
import Event
class Column:
TITLE=0
CATEGORY=1
class CategoryView(MVP.WidgetView):
"""
Widget: gtk.ComboBox
Model: ListStore
"""
def _initialize(self):
self._popup = None
self._widget.set_wrap_width(1)
title = gtk.CellRendererText()
self._widget.pack_start(title,False)
self._widget.add_attribute(title,'text',Column.TITLE)
self._widget.connect('changed', self._selection_changed)
return
def _model_set(self):
self._widget.set_model(self._model)
return
def _selection_changed(self, combo, data=None):
self._presenter.selection_changed(combo, data)
def set_active(self, index): self._widget.set_active(index)
def get_active(self): return self._widget.get_active()
def get_active_iter(self): return self._widget.get_active_iter()
def set_active_iter(self, it): self._widget.set_active_iter(it)
class CategoryPresenter(MVP.BasicPresenter):
def _initialize(self):
self.initialize_slots(Event.CategorySelectionChangedSignal)
self.model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
self.model.set_sort_func(Column.TITLE, self._sort_func)
self.model.set_sort_column_id(Column.TITLE, gtk.SORT_ASCENDING)
self._init_signals()
return
def _sort_func(self, model, a, b):
"""
From the gtk.TreeSortable.set_sort_func doc:
The comparison callback should return -1 if the iter1 row should come before
the iter2 row, 0 if the rows are equal, or 1 if the iter1 row should come
after the iter2 row.
"""
fclist = FeedCategoryList.get_instance()
retval = 0
cat_a = model.get_value(a, Column.CATEGORY)
cat_b = model.get_value(b, Column.CATEGORY)
if cat_a in fclist.pseudo_categories:
retval = -1
elif cat_b in fclist.pseudo_categories:
retval = 1
elif cat_a is not None and cat_b is not None:
retval = locale.strcoll(cat_a.title, cat_b.title)
elif cat_a is not None: retval = -1
elif cat_b is not None: retval = 1
return retval
def _init_signals(self):
fclist = FeedCategoryList.get_instance()
fclist.signal_connect(Event.FeedCategoryListLoadedSignal,
self._display_categories)
fclist.signal_connect(Event.FeedCategoryAddedSignal,
self._category_added_cb)
fclist.signal_connect(Event.FeedCategoryRemovedSignal,
self._category_removed_cb)
fclist.signal_connect(Event.FeedCategoryChangedSignal,
self._category_changed_cb)
return
def _get_selected_category(self):
category = None
if len(self._model):
active = self._view.get_active()
category = self._model[active][Column.CATEGORY]
return category
def _category_added_cb(self, signal):
newcat = signal.category
treeiter = self._model.append()
self._model.set(treeiter,
Column.TITLE, newcat.title,
Column.CATEGORY, newcat)
return
def _category_removed_cb(self, signal):
self._model.foreach(self._foreach_remove_cat,
signal.category)
self._update_selection()
return
def _foreach_remove_cat(self, model, path, iter, category):
cat = model[path][Column.CATEGORY]
if cat is category:
model.remove(iter)
return True
return False
def _category_changed_cb(self, signal):
self._model.foreach(self._foreach_category_changed,
signal.sender)
self._update_selection()
return
def _foreach_category_changed(self, model, path, iter, category):
cat = model[path][Column.CATEGORY]
if cat is category:
model.set(iter,
Column.TITLE, category.title,
Column.CATEGORY, category)
return True
return False
def _display_categories(self, signal):
fclist = signal.sender
self._model.clear()
for category in fclist.pseudo_categories:
it = self._model.append()
self._model.set(it,
Column.TITLE, category.title,
Column.CATEGORY, category)
for category in fclist.user_categories:
it = self._model.append()
self._model.set(it,
Column.TITLE, category.title,
Column.CATEGORY, category)
self._update_selection()
return
def _update_selection(self):
active = self._view.get_active()
if active < 0:
self._view.set_active_iter(self._model.get_iter_first())
return
def selection_changed(self, combo, data=None):
model = combo.get_model()
newitem = model[combo.get_active()][1]
self.emit_signal(Event.CategorySelectionChangedSignal(self,newitem))
return
def category_selected(self, category):
self._model.foreach(self._foreach_category_selected,
category)
self._update_selection()
def _foreach_category_selected(self, model, path, iter, category):
cat = model[path][Column.CATEGORY]
if cat is category:
self._view.set_active_iter(iter)
return True
return False
syntax highlighted by Code2HTML, v. 0.9.1