|
|
@ -37,6 +37,20 @@ from mitterlib.ui.helpers.image_helpers import find_image |
|
|
|
|
|
|
|
|
|
|
|
_log = logging.getLogger('ui.pygtk') |
|
|
|
_log = logging.getLogger('ui.pygtk') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------------------- |
|
|
|
|
|
|
|
# Helper Functions (not related to objects or that don't need direct access to |
|
|
|
|
|
|
|
# the objects contents.) |
|
|
|
|
|
|
|
# ---------------------------------------------------------------------- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _buffer_text(text_buffer): |
|
|
|
|
|
|
|
"""Return the content of a gtk.TextBuffer.""" |
|
|
|
|
|
|
|
start = text_buffer.get_start_iter() |
|
|
|
|
|
|
|
end = text_buffer.get_end_iter() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
text = text_buffer.get_text(start, end, include_hidden_chars=False) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return text |
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------------------- |
|
|
|
# ---------------------------------------------------------------------- |
|
|
|
# Threading related objects. |
|
|
|
# Threading related objects. |
|
|
|
# These classes are based on the code available at http://gist.github.com/51686 |
|
|
|
# These classes are based on the code available at http://gist.github.com/51686 |
|
|
@ -173,28 +187,6 @@ class Interface(object): |
|
|
|
about_window.hide() |
|
|
|
about_window.hide() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ------------------------------------------------------------ |
|
|
|
|
|
|
|
# Helper functions |
|
|
|
|
|
|
|
# ------------------------------------------------------------ |
|
|
|
|
|
|
|
def _sort_by_time(self, model, iter1, iter2, data=None): |
|
|
|
|
|
|
|
"""The sort function where we sort by the datetime.datetime object""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d1 = model.get_value(iter1, Columns.DATETIME) |
|
|
|
|
|
|
|
d2 = model.get_value(iter2, Columns.DATETIME) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Why do we get called with None values?! |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not d1: |
|
|
|
|
|
|
|
return 1 |
|
|
|
|
|
|
|
if not d2: |
|
|
|
|
|
|
|
return -1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if d1 < d2: |
|
|
|
|
|
|
|
return -1 |
|
|
|
|
|
|
|
elif d1 > d2: |
|
|
|
|
|
|
|
return 1 |
|
|
|
|
|
|
|
return 0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ------------------------------------------------------------ |
|
|
|
# ------------------------------------------------------------ |
|
|
|
# Widget creation functions |
|
|
|
# Widget creation functions |
|
|
|
# ------------------------------------------------------------ |
|
|
|
# ------------------------------------------------------------ |
|
|
@ -257,8 +249,8 @@ class Interface(object): |
|
|
|
self.grid_store = gtk.ListStore(object) |
|
|
|
self.grid_store = gtk.ListStore(object) |
|
|
|
# Trying to store the NetworkData object only |
|
|
|
# Trying to store the NetworkData object only |
|
|
|
|
|
|
|
|
|
|
|
self.grid_store.set_sort_func(0, self._sort_by_time) |
|
|
|
# self.grid_store.set_sort_func(0, self._sort_by_time) |
|
|
|
self.grid_store.set_sort_column_id(0, gtk.SORT_DESCENDING) |
|
|
|
# self.grid_store.set_sort_column_id(0, gtk.SORT_DESCENDING) |
|
|
|
|
|
|
|
|
|
|
|
self.grid = gtk.TreeView(self.grid_store) |
|
|
|
self.grid = gtk.TreeView(self.grid_store) |
|
|
|
self.grid.set_property('headers-visible', False) |
|
|
|
self.grid.set_property('headers-visible', False) |
|
|
@ -311,10 +303,10 @@ class Interface(object): |
|
|
|
'Settings', gtk.STOCK_PREFERENCES) |
|
|
|
'Settings', gtk.STOCK_PREFERENCES) |
|
|
|
#settings_action.connect('activate', self.show_settings) |
|
|
|
#settings_action.connect('activate', self.show_settings) |
|
|
|
|
|
|
|
|
|
|
|
update_action = gtk.Action('Update', '_Update', 'Update your status', |
|
|
|
self._update_action = gtk.Action('Update', '_Update', |
|
|
|
gtk.STOCK_ADD) |
|
|
|
'Update your status', gtk.STOCK_ADD) |
|
|
|
update_action.set_property('sensitive', False) |
|
|
|
self._update_action.set_property('sensitive', False) |
|
|
|
update_action.connect('activate', self._update_status) |
|
|
|
self._update_action.connect('activate', self._update_status) |
|
|
|
|
|
|
|
|
|
|
|
delete_action = gtk.Action('Delete', '_Delete', 'Delete a post', |
|
|
|
delete_action = gtk.Action('Delete', '_Delete', 'Delete a post', |
|
|
|
gtk.STOCK_DELETE) |
|
|
|
gtk.STOCK_DELETE) |
|
|
@ -355,7 +347,7 @@ class Interface(object): |
|
|
|
self.action_group.add_action(about_action) |
|
|
|
self.action_group.add_action(about_action) |
|
|
|
#self.action_group.add_action_with_accel(shrink_url_action, '<Ctrl>u') |
|
|
|
#self.action_group.add_action_with_accel(shrink_url_action, '<Ctrl>u') |
|
|
|
#self.action_group.add_action_with_accel(mute_action, '<Ctrl>m') |
|
|
|
#self.action_group.add_action_with_accel(mute_action, '<Ctrl>m') |
|
|
|
self.action_group.add_action_with_accel(update_action, |
|
|
|
self.action_group.add_action_with_accel(self._update_action, |
|
|
|
'<Ctrl>Return') |
|
|
|
'<Ctrl>Return') |
|
|
|
|
|
|
|
|
|
|
|
# definition of the UI |
|
|
|
# definition of the UI |
|
|
@ -404,13 +396,14 @@ class Interface(object): |
|
|
|
text_buffer = self._update_text.get_buffer() |
|
|
|
text_buffer = self._update_text.get_buffer() |
|
|
|
text_buffer.connect('changed', self._count_chars) |
|
|
|
text_buffer.connect('changed', self._count_chars) |
|
|
|
|
|
|
|
|
|
|
|
update_button = gtk.Button(stock=gtk.STOCK_ADD) |
|
|
|
self._update_button = gtk.Button(stock=gtk.STOCK_ADD) |
|
|
|
update_button.connect('clicked', self._update_status) |
|
|
|
self._update_button.connect('clicked', self._update_status) |
|
|
|
|
|
|
|
self._update_button.set_property('sensitive', False) |
|
|
|
|
|
|
|
|
|
|
|
update_box = gtk.HBox(False, 0) |
|
|
|
update_box = gtk.HBox(False, 0) |
|
|
|
update_box.pack_start(self._update_text, expand=True, fill=True, |
|
|
|
update_box.pack_start(self._update_text, expand=True, fill=True, |
|
|
|
padding=0) |
|
|
|
padding=0) |
|
|
|
update_box.pack_start(update_button, expand=False, fill=False, |
|
|
|
update_box.pack_start(self._update_button, expand=False, fill=False, |
|
|
|
padding=0) |
|
|
|
padding=0) |
|
|
|
|
|
|
|
|
|
|
|
info_box = gtk.HBox(False, 0) |
|
|
|
info_box = gtk.HBox(False, 0) |
|
|
@ -480,6 +473,7 @@ class Interface(object): |
|
|
|
|
|
|
|
|
|
|
|
return |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ------------------------------------------------------------ |
|
|
|
# ------------------------------------------------------------ |
|
|
|
# Widget callback functions |
|
|
|
# Widget callback functions |
|
|
|
# ------------------------------------------------------------ |
|
|
|
# ------------------------------------------------------------ |
|
|
@ -487,26 +481,28 @@ class Interface(object): |
|
|
|
def _count_chars(self, text_buffer): |
|
|
|
def _count_chars(self, text_buffer): |
|
|
|
"""Count the number of chars in the edit field and update the |
|
|
|
"""Count the number of chars in the edit field and update the |
|
|
|
label that shows the available space.""" |
|
|
|
label that shows the available space.""" |
|
|
|
|
|
|
|
text = _buffer_text(text_buffer) |
|
|
|
|
|
|
|
count = len(text) |
|
|
|
|
|
|
|
|
|
|
|
start = text_buffer.get_start_iter() |
|
|
|
self._char_count.set_text('(%d)' % (140 - count)) |
|
|
|
end = text_buffer.get_end_iter() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
text = text_buffer.get_text(start, end, include_hidden_chars=False) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self._char_count.set_text('(%d)' % (140 - len(text))) |
|
|
|
self._update_button.set_property('sensitive', not (count == 0)) |
|
|
|
|
|
|
|
self._update_action.set_property('sensitive', not (count == 0)) |
|
|
|
|
|
|
|
|
|
|
|
return True |
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
def _update_status(self): |
|
|
|
def _update_status(self, widget): |
|
|
|
"""Update your status.""" |
|
|
|
"""Update your status.""" |
|
|
|
_log.debug('Updating status.') |
|
|
|
_log.debug('Updating status.') |
|
|
|
status = self._update_text.get_text() |
|
|
|
status = _buffer_text(self._update_text.get_buffer()) |
|
|
|
status = status.strip() |
|
|
|
status = status.strip() |
|
|
|
if not str_len(status): |
|
|
|
if not status: |
|
|
|
return |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
self.update_text.set_sensitive(False) |
|
|
|
_log.debug('Status: %s', status) |
|
|
|
self.statusbar.push(self.statusbar_context, 'Updating your status...') |
|
|
|
|
|
|
|
|
|
|
|
#self._update_text.set_sensitive(False) |
|
|
|
|
|
|
|
#self.statusbar.push(self.statusbar_context, 'Updating your status...') |
|
|
|
|
|
|
|
|
|
|
|
def quit_app(self, widget=None, user_data=None): |
|
|
|
def quit_app(self, widget=None, user_data=None): |
|
|
|
"""Callback when the window is destroyed or the user selects |
|
|
|
"""Callback when the window is destroyed or the user selects |
|
|
@ -530,7 +526,9 @@ class Interface(object): |
|
|
|
# ------------------------------------------------------------ |
|
|
|
# ------------------------------------------------------------ |
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, connection, options): |
|
|
|
def __init__(self, connection, options): |
|
|
|
"""Class initialization.""" |
|
|
|
"""Start the interface. `connection` is the :class:`Networks` object |
|
|
|
|
|
|
|
with all the available networks. `options` is the :class:`ConfigOpt` |
|
|
|
|
|
|
|
object with the configuration to run Mitter.""" |
|
|
|
|
|
|
|
|
|
|
|
self._connection = connection |
|
|
|
self._connection = connection |
|
|
|
self._options = options |
|
|
|
self._options = options |
|
|
@ -567,6 +565,7 @@ class Interface(object): |
|
|
|
# self.set_auto_refresh() |
|
|
|
# self.set_auto_refresh() |
|
|
|
|
|
|
|
|
|
|
|
# self.window.set_focus(self.update_text) |
|
|
|
# self.window.set_focus(self.update_text) |
|
|
|
|
|
|
|
|
|
|
|
return |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
def __call__(self): |
|
|
|
def __call__(self): |
|
|
|