Commit f57fb537 authored by Luci Stanescu's avatar Luci Stanescu

Added support for the bonjour neighbours group

parent 79d2f4dd
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
from __future__ import with_statement from __future__ import with_statement
__all__ = ['Contact', 'ContactGroup', 'ContactModel', 'ContactSearchModel', 'ContactListView', 'ContactSearchListView'] __all__ = ['BonjourGroup', 'BonjourNeighbour', 'Contact', 'ContactGroup', 'ContactModel', 'ContactSearchModel', 'ContactListView', 'ContactSearchListView']
import cPickle as pickle import cPickle as pickle
import errno import errno
...@@ -46,6 +46,11 @@ updates_contacts_db.counter = 0 ...@@ -46,6 +46,11 @@ updates_contacts_db.counter = 0
class ContactGroup(object): class ContactGroup(object):
savable = True
movable = True
editable = True
deletable = True
def __init__(self, name, collapsed=False): def __init__(self, name, collapsed=False):
self.user_collapsed = collapsed self.user_collapsed = collapsed
self.name = name self.name = name
...@@ -122,6 +127,11 @@ class ContactIconDescriptor(object): ...@@ -122,6 +127,11 @@ class ContactIconDescriptor(object):
class Contact(object): class Contact(object):
savable = True
movable = True
editable = True
deletable = True
default_user_icon = ContactIconDescriptor('icons/default-avatar.png') default_user_icon = ContactIconDescriptor('icons/default-avatar.png')
def __init__(self, group, name, uri, image=None): def __init__(self, group, name, uri, image=None):
...@@ -142,6 +152,24 @@ class Contact(object): ...@@ -142,6 +152,24 @@ class Contact(object):
return (self.__class__, (self.group, self.name, self.uri, self.image), None) return (self.__class__, (self.group, self.name, self.uri, self.image), None)
class BonjourGroup(ContactGroup):
savable = True
movable = True
editable = True
deletable = False
def __init__(self, name, collapsed=False):
super(BonjourGroup, self).__init__(name, collapsed)
self.previous_position = None
class BonjourNeighbour(Contact):
savable = False
movable = False
editable = False
deletable = False
ui_class, base_class = uic.loadUiType(Resources.get('contact.ui')) ui_class, base_class = uic.loadUiType(Resources.get('contact.ui'))
class ContactWidget(base_class, ui_class): class ContactWidget(base_class, ui_class):
...@@ -295,7 +323,7 @@ del ui_class, base_class ...@@ -295,7 +323,7 @@ del ui_class, base_class
class ContactDelegate(QStyledItemDelegate): class ContactDelegate(QStyledItemDelegate):
item_size_hints = {Contact: QSize(200, 36), ContactGroup: QSize(200, 18)} item_size_hints = {Contact: QSize(200, 36), ContactGroup: QSize(200, 18), BonjourNeighbour: QSize(200, 36), BonjourGroup: QSize(200, 18)}
def __init__(self, parent=None): def __init__(self, parent=None):
super(ContactDelegate, self).__init__(parent) super(ContactDelegate, self).__init__(parent)
...@@ -321,13 +349,13 @@ class ContactDelegate(QStyledItemDelegate): ...@@ -321,13 +349,13 @@ class ContactDelegate(QStyledItemDelegate):
list_view = self.parent() list_view = self.parent()
list_items = list_view.model().items list_items = list_view.model().items
for position in xrange(list_items.index(group)+1, len(list_items)): for position in xrange(list_items.index(group)+1, len(list_items)):
if type(list_items[position]) is ContactGroup: if isinstance(list_items[position], ContactGroup):
break break
list_view.setRowHidden(position, collapsed) list_view.setRowHidden(position, collapsed)
def createEditor(self, parent, options, index): def createEditor(self, parent, options, index):
item = index.model().data(index, Qt.DisplayRole) item = index.model().data(index, Qt.DisplayRole)
if type(item) is ContactGroup: if isinstance(item, ContactGroup):
item.widget = ContactGroupWidget(item.name, parent) item.widget = ContactGroupWidget(item.name, parent)
item.widget.collapse_button.toggled.connect(partial(self._update_list_view, item)) item.widget.collapse_button.toggled.connect(partial(self._update_list_view, item))
return item.widget return item.widget
...@@ -392,6 +420,9 @@ class ContactDelegate(QStyledItemDelegate): ...@@ -392,6 +420,9 @@ class ContactDelegate(QStyledItemDelegate):
painter.drawPixmap(option.rect, pixmap) painter.drawPixmap(option.rect, pixmap)
painter.restore() painter.restore()
paintBonjourNeighbour = paintContact
paintBonjourGroup = paintContactGroup
def paint(self, painter, option, index): def paint(self, painter, option, index):
item = index.model().data(index, Qt.DisplayRole) item = index.model().data(index, Qt.DisplayRole)
handler = getattr(self, 'paint%s' % item.__class__.__name__, Null) handler = getattr(self, 'paint%s' % item.__class__.__name__, Null)
...@@ -416,10 +447,11 @@ class ContactModel(QAbstractListModel): ...@@ -416,10 +447,11 @@ class ContactModel(QAbstractListModel):
self.endResetModel = self.reset self.endResetModel = self.reset
self.save_queue = EventQueue(self.store_contacts, name='ContactsSavingThread') self.save_queue = EventQueue(self.store_contacts, name='ContactsSavingThread')
self.save_queue.start() self.save_queue.start()
self.bonjour_group = None
@property @property
def contact_groups(self): def contact_groups(self):
return [item for item in self.items if type(item) is ContactGroup] return [item for item in self.items if isinstance(item, ContactGroup)]
def flags(self, index): def flags(self, index):
if index.isValid(): if index.isValid():
...@@ -443,8 +475,8 @@ class ContactModel(QAbstractListModel): ...@@ -443,8 +475,8 @@ class ContactModel(QAbstractListModel):
def mimeData(self, indexes): def mimeData(self, indexes):
mime_data = QMimeData() mime_data = QMimeData()
contacts = [item for item in (self.items[index.row()] for index in indexes if index.isValid()) if type(item) is Contact] contacts = [item for item in (self.items[index.row()] for index in indexes if index.isValid()) if isinstance(item, Contact)]
groups = [item for item in (self.items[index.row()] for index in indexes if index.isValid()) if type(item) is ContactGroup] groups = [item for item in (self.items[index.row()] for index in indexes if index.isValid()) if isinstance(item, ContactGroup)]
if contacts: if contacts:
mime_data.setData('application/x-blink-contact-list', QByteArray(pickle.dumps(contacts))) mime_data.setData('application/x-blink-contact-list', QByteArray(pickle.dumps(contacts)))
if groups: if groups:
...@@ -476,7 +508,7 @@ class ContactModel(QAbstractListModel): ...@@ -476,7 +508,7 @@ class ContactModel(QAbstractListModel):
if group.widget.drop_indicator is None: if group.widget.drop_indicator is None:
return False return False
selected_indexes = self.contact_list.selectionModel().selectedIndexes() selected_indexes = self.contact_list.selectionModel().selectedIndexes()
moved_groups = set(self.items[index.row()] for index in selected_indexes if index.isValid()) moved_groups = set(self.items[index.row()] for index in selected_indexes if index.isValid() and self.items[index.row()].movable)
if group is contact_groups[0] and group in moved_groups: if group is contact_groups[0] and group in moved_groups:
drop_group = (group for group in contact_groups if group not in moved_groups).next() drop_group = (group for group in contact_groups if group not in moved_groups).next()
drop_position = self.contact_list.AboveItem drop_position = self.contact_list.AboveItem
...@@ -504,7 +536,7 @@ class ContactModel(QAbstractListModel): ...@@ -504,7 +536,7 @@ class ContactModel(QAbstractListModel):
self.items[position:position] = items self.items[position:position] = items
self.endInsertRows() self.endInsertRows()
for index, item in enumerate(items): for index, item in enumerate(items):
if type(item) is ContactGroup: if isinstance(item, ContactGroup):
self.contact_list.openPersistentEditor(self.index(position+index)) self.contact_list.openPersistentEditor(self.index(position+index))
else: else:
self.contact_list.setRowHidden(position+index, item.group.collapsed) self.contact_list.setRowHidden(position+index, item.group.collapsed)
...@@ -515,7 +547,8 @@ class ContactModel(QAbstractListModel): ...@@ -515,7 +547,8 @@ class ContactModel(QAbstractListModel):
group = self.items[index.row()] if index.isValid() else self.contact_groups[-1] group = self.items[index.row()] if index.isValid() else self.contact_groups[-1]
if group.widget.drop_indicator is None: if group.widget.drop_indicator is None:
return False return False
for contact in self.popItems(self.contact_list.selectionModel().selectedIndexes()): indexes = [index for index in self.contact_list.selectionModel().selectedIndexes() if self.items[index.row()].movable]
for contact in self.popItems(indexes):
contact.group = group contact.group = group
self.addContact(contact) self.addContact(contact)
return True return True
...@@ -558,7 +591,7 @@ class ContactModel(QAbstractListModel): ...@@ -558,7 +591,7 @@ class ContactModel(QAbstractListModel):
if contact.group in self.items: if contact.group in self.items:
for position in xrange(self.items.index(contact.group)+1, len(self.items)): for position in xrange(self.items.index(contact.group)+1, len(self.items)):
item = self.items[position] item = self.items[position]
if type(item) is ContactGroup or item.name > contact.name: if isinstance(item, ContactGroup) or item.name > contact.name:
break break
else: else:
position = len(self.items) position = len(self.items)
...@@ -598,20 +631,47 @@ class ContactModel(QAbstractListModel): ...@@ -598,20 +631,47 @@ class ContactModel(QAbstractListModel):
if group not in self.items: if group not in self.items:
return return
start = self.items.index(group) start = self.items.index(group)
end = start + len([item for item in self.items if type(item) is Contact and item.group==group]) end = start + len([item for item in self.items if isinstance(item, Contact) and item.group==group])
self.beginRemoveRows(QModelIndex(), start, end)
del self.items[start:end+1]
self.endRemoveRows()
@updates_contacts_db
def moveGroup(self, group, position):
contact_groups = self.contact_groups
if group not in contact_groups or contact_groups.index(group) == position:
return
contacts_count = len([item for item in self.items if isinstance(item, Contact) and item.group==group])
start = self.items.index(group)
end = start + contacts_count
self.beginRemoveRows(QModelIndex(), start, end) self.beginRemoveRows(QModelIndex(), start, end)
items = self.items[start:end+1]
del self.items[start:end+1] del self.items[start:end+1]
self.endRemoveRows() self.endRemoveRows()
if position >= len(contact_groups)-1:
self.beginInsertRows(QModelIndex(), len(self.items), len(self.items)+end)
self.items.extend(items)
self.endInsertRows()
self.contact_list.openPersistentEditor(self.index(len(self.items)-contacts_count-1))
else:
if contact_groups.index(group) < position:
position += 1
start = self.items.index(contact_groups[position])
end = start + contacts_count
self.beginInsertRows(QModelIndex(), start, end)
self.items[start:start] = items
self.endInsertRows()
self.contact_list.openPersistentEditor(self.index(start))
@updates_contacts_db @updates_contacts_db
def removeItems(self, indexes): def removeItems(self, indexes):
rows = set(index.row() for index in indexes if index.isValid()) rows = set(index.row() for index in indexes if index.isValid())
removed_groups = set(self.items[row] for row in rows if type(self.items[row]) is ContactGroup) removed_groups = set(self.items[row] for row in rows if isinstance(self.items[row], ContactGroup))
rows.update(row for row, item in enumerate(self.items) if type(item) is Contact and item.group in removed_groups) rows.update(row for row, item in enumerate(self.items) if isinstance(item, Contact) and item.group in removed_groups)
for start, end in self.reversed_range_iterator(rows): for start, end in self.reversed_range_iterator(rows):
self.beginRemoveRows(QModelIndex(), start, end) self.beginRemoveRows(QModelIndex(), start, end)
deleted_items = self.items[start:end+1] deleted_items = self.items[start:end+1]
for item in (item for item in deleted_items if type(item) is ContactGroup): for item in (item for item in deleted_items if isinstance(item, ContactGroup)):
item.widget = Null item.widget = Null
self.deleted_items.append(deleted_items) self.deleted_items.append(deleted_items)
del self.items[start:end+1] del self.items[start:end+1]
...@@ -621,8 +681,8 @@ class ContactModel(QAbstractListModel): ...@@ -621,8 +681,8 @@ class ContactModel(QAbstractListModel):
def popItems(self, indexes): def popItems(self, indexes):
items = [] items = []
rows = set(index.row() for index in indexes if index.isValid()) rows = set(index.row() for index in indexes if index.isValid())
removed_groups = set(self.items[row] for row in rows if type(self.items[row]) is ContactGroup) removed_groups = set(self.items[row] for row in rows if isinstance(self.items[row], ContactGroup))
rows.update(row for row, item in enumerate(self.items) if type(item) is Contact and item.group in removed_groups) rows.update(row for row, item in enumerate(self.items) if isinstance(item, Contact) and item.group in removed_groups)
for start, end in self.reversed_range_iterator(rows): for start, end in self.reversed_range_iterator(rows):
self.beginRemoveRows(QModelIndex(), start, end) self.beginRemoveRows(QModelIndex(), start, end)
items[0:0] = self.items[start:end+1] items[0:0] = self.items[start:end+1]
...@@ -657,15 +717,28 @@ class ContactModel(QAbstractListModel): ...@@ -657,15 +717,28 @@ class ContactModel(QAbstractListModel):
self.items = items self.items = items
self.endResetModel() self.endResetModel()
for position, item in enumerate(self.items): for position, item in enumerate(self.items):
if type(item) is ContactGroup: if isinstance(item, ContactGroup):
self.contact_list.openPersistentEditor(self.index(position)) self.contact_list.openPersistentEditor(self.index(position))
else: else:
self.contact_list.setRowHidden(position, item.group.collapsed) self.contact_list.setRowHidden(position, item.group.collapsed)
if type(item) is BonjourGroup:
self.bonjour_group = item
if self.bonjour_group is None:
self.bonjour_group = BonjourGroup('Bonjour Neighbours')
if file is None: if file is None:
self.save() self.save()
def save(self): def save(self):
self.save_queue.put(pickle.dumps(self.items)) items = [item for item in self.items if item.savable]
contact_groups = self.contact_groups
if self.bonjour_group in contact_groups and self.bonjour_group.previous_position != contact_groups.index(self.bonjour_group) and self.bonjour_group.previous_position is not None:
items.remove(self.bonjour_group)
if self.bonjour_group.previous_position >= len(contact_groups)-1:
items.append(self.bonjour_group)
else:
position = items.index(contact_groups[self.bonjour_group.previous_position+1])
items.insert(position, self.bonjour_group)
self.save_queue.put(pickle.dumps(items))
def store_contacts(self, data): def store_contacts(self, data):
makedirs(ApplicationData.directory) makedirs(ApplicationData.directory)
...@@ -740,7 +813,7 @@ class ContactSearchModel(QSortFilterProxyModel): ...@@ -740,7 +813,7 @@ class ContactSearchModel(QSortFilterProxyModel):
source_model = self.sourceModel() source_model = self.sourceModel()
source_index = source_model.index(source_row, 0, source_parent) source_index = source_model.index(source_row, 0, source_parent)
item = source_model.data(source_index, Qt.DisplayRole) item = source_model.data(source_index, Qt.DisplayRole)
if type(item) is ContactGroup: if isinstance(item, ContactGroup):
return False return False
search_tokens = unicode(self.filterRegExp().pattern()).lower().split() search_tokens = unicode(self.filterRegExp().pattern()).lower().split()
searched_item = unicode(item).lower() searched_item = unicode(item).lower()
...@@ -826,13 +899,16 @@ class ContactListView(QListView): ...@@ -826,13 +899,16 @@ class ContactListView(QListView):
menu.addAction(self.actions.add_contact) menu.addAction(self.actions.add_contact)
menu.addAction(self.actions.delete_selection) menu.addAction(self.actions.delete_selection)
menu.addAction(self.actions.undo_last_delete) menu.addAction(self.actions.undo_last_delete)
self.actions.delete_selection.setEnabled(any(item.deletable for item in selected_items))
self.actions.undo_last_delete.setEnabled(len(model.deleted_items) > 0) self.actions.undo_last_delete.setEnabled(len(model.deleted_items) > 0)
elif type(selected_items[0]) is ContactGroup: elif isinstance(selected_items[0], ContactGroup):
menu.addAction(self.actions.add_group) menu.addAction(self.actions.add_group)
menu.addAction(self.actions.add_contact) menu.addAction(self.actions.add_contact)
menu.addAction(self.actions.edit_item) menu.addAction(self.actions.edit_item)
menu.addAction(self.actions.delete_item) menu.addAction(self.actions.delete_item)
menu.addAction(self.actions.undo_last_delete) menu.addAction(self.actions.undo_last_delete)
self.actions.edit_item.setEnabled(selected_items[0].editable)
self.actions.delete_item.setEnabled(selected_items[0].deletable)
self.actions.undo_last_delete.setEnabled(len(model.deleted_items) > 0) self.actions.undo_last_delete.setEnabled(len(model.deleted_items) > 0)
else: else:
contact = selected_items[0] contact = selected_items[0]
...@@ -852,6 +928,8 @@ class ContactListView(QListView): ...@@ -852,6 +928,8 @@ class ContactListView(QListView):
menu.addAction(self.actions.edit_item) menu.addAction(self.actions.edit_item)
menu.addAction(self.actions.delete_item) menu.addAction(self.actions.delete_item)
menu.addAction(self.actions.undo_last_delete) menu.addAction(self.actions.undo_last_delete)
self.actions.edit_item.setEnabled(contact.editable)
self.actions.delete_item.setEnabled(contact.deletable)
self.actions.undo_last_delete.setEnabled(len(model.deleted_items) > 0) self.actions.undo_last_delete.setEnabled(len(model.deleted_items) > 0)
menu.exec_(event.globalPos()) menu.exec_(event.globalPos())
...@@ -933,29 +1011,33 @@ class ContactListView(QListView): ...@@ -933,29 +1011,33 @@ class ContactListView(QListView):
def _AH_AddContact(self): def _AH_AddContact(self):
model = self.model() model = self.model()
selected_rows = sorted(index.row() for index in self.selectionModel().selectedIndexes()) selected_rows = sorted(index.row() for index in self.selectionModel().selectedIndexes() if type(model.data(index)) in (Contact, ContactGroup))
if selected_rows: if selected_rows:
item = model.items[selected_rows[0]] item = model.items[selected_rows[0]]
prefered_group = item if type(item) is ContactGroup else item.group preferred_group = item if type(item) is ContactGroup else item.group
elif model.items:
prefered_group = model.items[0]
else: else:
prefered_group = None try:
preferred_group = (group for group in model.contact_groups if type(group) is ContactGroup).next()
except StopIteration:
preferred_group = None
def _AH_EditItem(self): def _AH_EditItem(self):
index = self.selectionModel().selectedIndexes()[0] index = self.selectionModel().selectedIndexes()[0]
item = self.model().data(index) item = self.model().data(index)
if type(item) is ContactGroup: if isinstance(item, ContactGroup):
self.scrollTo(index) self.scrollTo(index)
item.widget.edit() item.widget.edit()
def _AH_DeleteSelection(self): def _AH_DeleteSelection(self):
self.model().removeItems(self.selectionModel().selectedIndexes()) model = self.model()
indexes = [index for index in self.selectionModel().selectedIndexes() if model.items[index.row()].deletable]
model.removeItems(indexes)
self.selectionModel().clearSelection()
def _AH_UndoLastDelete(self): def _AH_UndoLastDelete(self):
model = self.model() model = self.model()
for item in model.deleted_items.pop(): for item in model.deleted_items.pop():
handler = model.addGroup if type(item) is ContactGroup else model.addContact handler = model.addGroup if isinstance(item, ContactGroup) else model.addContact
handler(item) handler(item)
def _AH_StartAudioSession(self): def _AH_StartAudioSession(self):
...@@ -985,7 +1067,7 @@ class ContactListView(QListView): ...@@ -985,7 +1067,7 @@ class ContactListView(QListView):
drop_groups = (groups[-1], Null) drop_groups = (groups[-1], Null)
rect = self.viewport().rect() rect = self.viewport().rect()
rect.setTop(self.visualRect(model.index(model.items.index(groups[-1]))).bottom()) rect.setTop(self.visualRect(model.index(model.items.index(groups[-1]))).bottom())
elif type(item) is ContactGroup: elif isinstance(item, ContactGroup):
index = groups.index(item) index = groups.index(item)
rect.setHeight(rect.height()/2) rect.setHeight(rect.height()/2)
if rect.contains(event.pos()): if rect.contains(event.pos()):
...@@ -993,7 +1075,7 @@ class ContactListView(QListView): ...@@ -993,7 +1075,7 @@ class ContactListView(QListView):
else: else:
drop_groups = (groups[index], groups[index+1]) if index<len(groups)-1 else (groups[index], Null) drop_groups = (groups[index], groups[index+1]) if index<len(groups)-1 else (groups[index], Null)
rect.translate(0, rect.height()) rect.translate(0, rect.height())
selected_rows = sorted(index.row() for index in self.selectionModel().selectedIndexes()) selected_rows = sorted(index.row() for index in self.selectionModel().selectedIndexes() if model.items[index.row()].movable)
if selected_rows: if selected_rows:
first = groups.index(model.items[selected_rows[0]]) first = groups.index(model.items[selected_rows[0]])
last = groups.index(model.items[selected_rows[-1]]) last = groups.index(model.items[selected_rows[-1]])
...@@ -1015,14 +1097,17 @@ class ContactListView(QListView): ...@@ -1015,14 +1097,17 @@ class ContactListView(QListView):
groups = model.contact_groups groups = model.contact_groups
for group in groups: for group in groups:
group.widget.drop_indicator = None group.widget.drop_indicator = None
if not any(model.items[index.row()].movable for index in self.selectionModel().selectedIndexes()):
event.accept(rect)
return
if not index.isValid(): if not index.isValid():
group = groups[-1] group = groups[-1]
rect = self.viewport().rect() rect = self.viewport().rect()
rect.setTop(self.visualRect(model.index(model.items.index(group))).bottom()) rect.setTop(self.visualRect(model.index(model.items.index(group))).bottom())
elif type(item) is ContactGroup: elif isinstance(item, ContactGroup):
group = item group = item
selected_contact_groups = set(model.items[index.row()].group for index in self.selectionModel().selectedIndexes()) selected_contact_groups = set(model.items[index.row()].group for index in self.selectionModel().selectedIndexes() if model.items[index.row()].movable)
if event.source() is not self or len(selected_contact_groups) > 1 or group not in selected_contact_groups: if type(group) is ContactGroup and (event.source() is not self or len(selected_contact_groups) > 1 or group not in selected_contact_groups):
group.widget.drop_indicator = self.OnItem group.widget.drop_indicator = self.OnItem
event.accept(rect) event.accept(rect)
...@@ -1031,7 +1116,7 @@ class ContactListView(QListView): ...@@ -1031,7 +1116,7 @@ class ContactListView(QListView):
if not index.isValid(): if not index.isValid():
rect = self.viewport().rect() rect = self.viewport().rect()
rect.setTop(self.visualRect(model.index(len(model.items)-1)).bottom()) rect.setTop(self.visualRect(model.index(len(model.items)-1)).bottom())
if type(item) is Contact: if isinstance(item, Contact):
event.accept(rect) event.accept(rect)
self.drop_indicator_index = index self.drop_indicator_index = index
else: else:
...@@ -1078,6 +1163,7 @@ class ContactSearchListView(QListView): ...@@ -1078,6 +1163,7 @@ class ContactSearchListView(QListView):
elif len(selected_items) > 1: elif len(selected_items) > 1:
menu.addAction(self.actions.delete_selection) menu.addAction(self.actions.delete_selection)
menu.addAction(self.actions.undo_last_delete) menu.addAction(self.actions.undo_last_delete)
self.actions.delete_selection.setEnabled(any(item.deletable for item in selected_items))
self.actions.undo_last_delete.setEnabled(len(source_model.deleted_items) > 0) self.actions.undo_last_delete.setEnabled(len(source_model.deleted_items) > 0)
else: else:
contact = selected_items[0] contact = selected_items[0]
...@@ -1095,6 +1181,8 @@ class ContactSearchListView(QListView): ...@@ -1095,6 +1181,8 @@ class ContactSearchListView(QListView):
menu.addAction(self.actions.edit_item) menu.addAction(self.actions.edit_item)
menu.addAction(self.actions.delete_item) menu.addAction(self.actions.delete_item)
menu.addAction(self.actions.undo_last_delete) menu.addAction(self.actions.undo_last_delete)
self.actions.edit_item.setEnabled(contact.editable)
self.actions.delete_item.setEnabled(contact.deletable)
self.actions.undo_last_delete.setEnabled(len(source_model.deleted_items) > 0) self.actions.undo_last_delete.setEnabled(len(source_model.deleted_items) > 0)
menu.exec_(event.globalPos()) menu.exec_(event.globalPos())
...@@ -1144,12 +1232,12 @@ class ContactSearchListView(QListView): ...@@ -1144,12 +1232,12 @@ class ContactSearchListView(QListView):
def _AH_DeleteSelection(self): def _AH_DeleteSelection(self):
model = self.model() model = self.model()
model.sourceModel().removeItems(model.mapToSource(index) for index in self.selectionModel().selectedIndexes()) model.sourceModel().removeItems(model.mapToSource(index) for index in self.selectionModel().selectedIndexes() if model.data(index).deletable)
def _AH_UndoLastDelete(self): def _AH_UndoLastDelete(self):
model = self.model().sourceModel() model = self.model().sourceModel()
for item in model.deleted_items.pop(): for item in model.deleted_items.pop():
handler = model.addGroup if type(item) is ContactGroup else model.addContact handler = model.addGroup if isinstance(item, ContactGroup) else model.addContact
handler(item) handler(item)
def _AH_StartAudioSession(self): def _AH_StartAudioSession(self):
......
...@@ -15,7 +15,7 @@ from zope.interface import implements ...@@ -15,7 +15,7 @@ from zope.interface import implements
from sipsimple.account import AccountManager, BonjourAccount from sipsimple.account import AccountManager, BonjourAccount
from blink.contacts import Contact, ContactModel, ContactSearchModel from blink.contacts import BonjourNeighbour, Contact, ContactModel, ContactSearchModel
from blink.resources import Resources from blink.resources import Resources
from blink.util import run_in_gui_thread from blink.util import run_in_gui_thread
...@@ -68,6 +68,8 @@ class MainWindow(base_class, ui_class): ...@@ -68,6 +68,8 @@ class MainWindow(base_class, ui_class):
#self.connect(self.contact_list, QtCore.SIGNAL("doubleClicked(const QModelIndex &)"), self.double_click_action) #self.connect(self.contact_list, QtCore.SIGNAL("doubleClicked(const QModelIndex &)"), self.double_click_action)
notification_center = NotificationCenter() notification_center = NotificationCenter()
notification_center.add_observer(self, name='BonjourAccountDidAddNeighbour')
notification_center.add_observer(self, name='BonjourAccountDidRemoveNeighbour')
notification_center.add_observer(self, name="SIPAccountManagerDidChangeDefaultAccount") notification_center.add_observer(self, name="SIPAccountManagerDidChangeDefaultAccount")
notification_center.add_observer(self, name="SIPAccountManagerDidStart") notification_center.add_observer(self, name="SIPAccountManagerDidStart")
notification_center.add_observer(self, name="SIPAccountDidActivate") notification_center.add_observer(self, name="SIPAccountDidActivate")
...@@ -139,11 +141,22 @@ class MainWindow(base_class, ui_class): ...@@ -139,11 +141,22 @@ class MainWindow(base_class, ui_class):
handler = getattr(self, '_NH_%s' % notification.name, Null) handler = getattr(self, '_NH_%s' % notification.name, Null)
handler(notification) handler(notification)
def _NH_BonjourAccountDidAddNeighbour(self, notification):
display_name = '%s (%s)' % (notification.data.display_name, notification.data.host)
contact = BonjourNeighbour(self.contact_model.bonjour_group, display_name, unicode(notification.data.uri))
self.contact_model.addContact(contact)
def _NH_BonjourAccountDidRemoveNeighbour(self, notification):
for contact in (c for c in self.contact_model.items[:] if type(c) is BonjourNeighbour):
if contact.uri == unicode(notification.data.uri):
self.contact_model.removeContact(contact)
def _NH_SIPAccountDidActivate(self, notification): def _NH_SIPAccountDidActivate(self, notification):
account = notification.sender account = notification.sender
name = u'Bonjour' if account is BonjourAccount() else account.id name = u'Bonjour' if account is BonjourAccount() else account.id
icon = None icon = None
if account is BonjourAccount(): if account is BonjourAccount():
self.contact_model.addGroup(self.contact_model.bonjour_group)
pixmap = QPixmap() pixmap = QPixmap()
if pixmap.load(Resources.get('icons/bonjour.png')): if pixmap.load(Resources.get('icons/bonjour.png')):
pixmap = pixmap.scaled(16, 16, Qt.KeepAspectRatio, Qt.SmoothTransformation) pixmap = pixmap.scaled(16, 16, Qt.KeepAspectRatio, Qt.SmoothTransformation)
...@@ -157,16 +170,38 @@ class MainWindow(base_class, ui_class): ...@@ -157,16 +170,38 @@ class MainWindow(base_class, ui_class):
account = notification.sender account = notification.sender
name = u'Bonjour' if account is BonjourAccount() else account.id name = u'Bonjour' if account is BonjourAccount() else account.id
self.identity.removeItem(self.identity.findText(name)) self.identity.removeItem(self.identity.findText(name))
if account is BonjourAccount():
self.contact_model.removeGroup(self.contact_model.bonjour_group)
def _NH_SIPAccountManagerDidStart(self, notification): def _NH_SIPAccountManagerDidStart(self, notification):
account = AccountManager().default_account account = AccountManager().default_account
name = u'Bonjour' if account is BonjourAccount() else account.id name = u'Bonjour' if account is BonjourAccount() else account.id
self.identity.setCurrentIndex(self.identity.findText(name)) self.identity.setCurrentIndex(self.identity.findText(name))
if not BonjourAccount().enabled and self.contact_model.bonjour_group in self.contact_model.contact_groups:
self.contact_model.removeGroup(self.contact_model.bonjour_group)
if notification.sender.default_account is BonjourAccount():
group = self.contact_model.bonjour_group
group.previous_position = self.contact_model.contact_groups.index(group)
self.contact_model.moveGroup(group, 0)
group.expand()
def _NH_SIPAccountManagerDidChangeDefaultAccount(self, notification): def _NH_SIPAccountManagerDidChangeDefaultAccount(self, notification):
account = notification.data.account account = notification.data.account
old_account = notification.data.old_account
name = u'Bonjour' if account is BonjourAccount() else account.id name = u'Bonjour' if account is BonjourAccount() else account.id
self.identity.setCurrentIndex(self.identity.findText(name)) self.identity.setCurrentIndex(self.identity.findText(name))
if account is BonjourAccount():
group = self.contact_model.bonjour_group
group.previous_position = self.contact_model.contact_groups.index(group)
self.contact_model.moveGroup(group, 0)
group.expand()
elif old_account is BonjourAccount():
group = self.contact_model.bonjour_group
self.contact_model.moveGroup(group, group.previous_position)
if group.collapsed and not group.user_collapsed:
group.expand()
elif not group.collapsed and group.user_collapsed:
group.collapse()
del ui_class, base_class del ui_class, base_class
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment