Commit 199f78a4 authored by Dan Pascu's avatar Dan Pascu

Implemented dragging contacts to conferences

parent 24ff5b7c
......@@ -1159,10 +1159,12 @@ class ContactListView(QListView):
for group in self.model().contact_groups:
group.restore_state()
self.needs_restore = False
self.model().main_window.switch_view_button.dnd_active = False
def dragEnterEvent(self, event):
model = self.model()
event_source = event.source()
accepted_mime_types = set(self.model().accepted_mime_types)
accepted_mime_types = set(model.accepted_mime_types)
provided_mime_types = set(str(x) for x in event.mimeData().formats())
acceptable_mime_types = accepted_mime_types & provided_mime_types
has_blink_contacts = 'application/x-blink-contact-list' in provided_mime_types
......@@ -1178,10 +1180,12 @@ class ContactListView(QListView):
event.setDropAction(Qt.MoveAction)
if has_blink_contacts or has_blink_groups:
if not self.needs_restore:
for group in self.model().contact_groups:
for group in model.contact_groups:
group.save_state()
group.collapse()
self.needs_restore = True
if has_blink_contacts:
model.main_window.switch_view_button.dnd_active = True
event.accept()
self.setState(self.DraggingState)
......@@ -1197,13 +1201,14 @@ class ContactListView(QListView):
if event.source() is self:
event.setDropAction(Qt.MoveAction)
for mime_type in self.model().accepted_mime_types:
model = self.model()
for mime_type in model.accepted_mime_types:
if event.provides(mime_type):
self.viewport().update(self.visualRect(self.drop_indicator_index))
self.drop_indicator_index = QModelIndex()
index = self.indexAt(event.pos())
rect = self.visualRect(index)
item = self.model().data(index)
item = model.data(index)
name = mime_type.replace('/', ' ').replace('-', ' ').title().replace(' ', '')
handler = getattr(self, '_DH_%s' % name)
handler(event, index, rect, item)
......@@ -1400,11 +1405,19 @@ class ContactSearchListView(QListView):
def _AH_ShareMyDesktop(self):
contact = self.model().data(self.selectionModel().selectedIndexes()[0])
def startDrag(self, supported_actions):
super(ContactSearchListView, self).startDrag(supported_actions)
self.model().main_window.switch_view_button.dnd_active = False
def dragEnterEvent(self, event):
accepted_mime_types = set(self.model().accepted_mime_types)
model = self.model()
accepted_mime_types = set(model.accepted_mime_types)
provided_mime_types = set(str(x) for x in event.mimeData().formats())
acceptable_mime_types = accepted_mime_types & provided_mime_types
if event.source() is self or not acceptable_mime_types:
if event.source() is self:
event.ignore()
model.main_window.switch_view_button.dnd_active = True
elif not acceptable_mime_types:
event.ignore()
else:
event.accept()
......
......@@ -15,6 +15,7 @@ from blink.accounts import AccountModel, ActiveAccountModel
from blink.contacts import Contact, ContactGroup, ContactEditorDialog, ContactModel, ContactSearchModel
from blink.sessions import SessionModel
from blink.resources import Resources
from blink.widgets.buttons import SwitchViewButton
ui_class, base_class = uic.loadUiType(Resources.get('blink.ui'))
......@@ -54,16 +55,11 @@ class MainWindow(base_class, ui_class):
self.session_list.selectionModel().selectionChanged.connect(self.session_list_selection_changed)
self.contacts_panel.sibling_panel = self.sessions_panel
self.contacts_panel.sibling_name = u'Switch to Calls'
self.sessions_panel.sibling_panel = self.contacts_panel
self.sessions_panel.sibling_name = u'Switch to Contacts'
self.main_view.setCurrentWidget(self.contacts_panel)
self.contacts_view.setCurrentWidget(self.contact_list_panel)
self.search_view.setCurrentWidget(self.search_list_panel)
self.switch_view_button.clicked.connect(self.switch_main_view)
self.switch_view_button.viewChanged.connect(self.switch_main_view)
self.search_box.textChanged.connect(self.search_box_text_changed)
self.contact_model.itemsAdded.connect(self.contact_model_added_items)
......@@ -119,8 +115,7 @@ class MainWindow(base_class, ui_class):
def search_box_text_changed(self, text):
if text:
self.main_view.setCurrentWidget(self.contacts_panel)
self.switch_view_button.setText(self.contacts_panel.sibling_name)
self.switch_view_button.view = SwitchViewButton.ContactView
self.enable_call_buttons(True)
else:
selected_items = self.contact_list.selectionModel().selectedIndexes()
......@@ -158,10 +153,8 @@ class MainWindow(base_class, ui_class):
active_session = self.session_model.data(selected_indexes[0])
self.conference_button.setChecked(active_session.conference is not None)
def switch_main_view(self):
widget = self.main_view.currentWidget().sibling_panel
self.main_view.setCurrentWidget(widget)
self.switch_view_button.setText(widget.sibling_name)
def switch_main_view(self, view):
self.main_view.setCurrentWidget(self.contacts_panel if view is SwitchViewButton.ContactView else self.sessions_panel)
del ui_class, base_class
......
# Copyright (c) 2010 AG Projects. See LICENSE for details.
#
__all__ = ['ToolButton', 'SegmentButton', 'SingleSegment', 'LeftSegment', 'MiddleSegment', 'RightSegment']
__all__ = ['ToolButton', 'SegmentButton', 'SingleSegment', 'LeftSegment', 'MiddleSegment', 'RightSegment', 'SwitchViewButton']
from PyQt4.QtCore import pyqtSignal
from PyQt4.QtGui import QStyle, QStyleOptionToolButton, QStylePainter, QToolButton
from PyQt4.QtCore import QTimer, pyqtSignal
from PyQt4.QtGui import QPushButton, QStyle, QStyleOptionToolButton, QStylePainter, QToolButton
class ToolButton(QToolButton):
......@@ -127,3 +127,127 @@ class SegmentButton(QToolButton):
self.shown.emit()
class SwitchViewButton(QPushButton):
ContactView = 0
SessionView = 1
viewChanged = pyqtSignal(int)
button_text = {ContactView: u'Switch to Calls', SessionView: u'Switch to Contacts'}
button_dnd_text = {ContactView: u'Drag here to add to a conference', SessionView: u'Drag here to go back to contacts'}
dnd_style_sheet1 = """
QPushButton {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #ffffff, stop:1 #d3ffdc);
border-color: #237523;
border-radius: 4px;
border-width: 2px;
border-style: solid;
}
"""
dnd_style_sheet2 = """
QPushButton {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #ffffff, stop:1 #c2ffce);
border-color: #dc3169;
border-radius: 4px;
border-width: 2px;
border-style: solid;
}
"""
def __init__(self, parent=None):
super(SwitchViewButton, self).__init__(parent)
self.setAcceptDrops(True)
self.__dict__['dnd_active'] = False
self.view = self.ContactView
self.original_height = 20 # used to restore button size after DND
self.dnd_timer = QTimer(self)
self.dnd_timer.setInterval(100)
self.dnd_timer.timeout.connect(self._update_dnd)
self.dnd_timer.phase = 0
self.clicked.connect(self._change_view)
def _get_view(self):
return self.__dict__['view']
def _set_view(self, value):
if self.__dict__.get('view', None) == value:
return
if value not in (self.ContactView, self.SessionView):
raise ValueError("invalid view value: %r" % value)
self.__dict__['view'] = value
if self.dnd_active:
text = self.button_dnd_text[value]
else:
text = self.button_text[value]
self.setText(text)
self.viewChanged.emit(value)
view = property(_get_view, _set_view)
del _get_view, _set_view
def _get_dnd_active(self):
return self.__dict__['dnd_active']
def _set_dnd_active(self, value):
if self.__dict__.get('dnd_active', None) == value:
return
self.__dict__['dnd_active'] = value
if value is True:
self.dnd_timer.phase = 0
self.setStyleSheet(self.dnd_style_sheet1)
self.setText(self.button_dnd_text[self.view])
self.original_height = self.height()
self.setMinimumHeight(40)
self.setMaximumHeight(40)
self.resize(self.width(), 40)
else:
self.setStyleSheet('')
self.setText(self.button_text[self.view])
height = self.original_height
self.setMinimumHeight(height)
self.setMaximumHeight(height)
self.resize(self.width(), height)
dnd_active = property(_get_dnd_active, _set_dnd_active)
del _get_dnd_active, _set_dnd_active
def _change_view(self):
self.view = self.ContactView if self.view is self.SessionView else self.SessionView
def _update_dnd(self):
self.dnd_timer.phase += 1
if self.dnd_timer.phase == 11:
self.dnd_timer.stop()
self.click()
self.setStyleSheet(self.dnd_style_sheet1)
else:
style_sheet = (self.dnd_style_sheet1, self.dnd_style_sheet2)[self.dnd_timer.phase % 2]
self.setStyleSheet(style_sheet)
def dragEnterEvent(self, event):
if not self.dnd_active:
event.ignore()
elif event.mimeData().formats() == ['application/x-blink-contact-list']:
event.accept()
self._update_dnd()
self.dnd_timer.start()
else:
event.ignore()
def dragLeaveEvent(self, event):
if self.dnd_active:
self.dnd_timer.stop()
self.dnd_timer.phase = 0
self.setStyleSheet(self.dnd_style_sheet1)
super(SwitchViewButton, self).dragLeaveEvent(event)
def dropEvent(self, event):
if self.dnd_active:
self.dnd_timer.stop()
self.dnd_timer.phase = 0
self.setStyleSheet(self.dnd_style_sheet1)
event.ignore()
......@@ -224,7 +224,7 @@
</layout>
</item>
<item>
<widget class="QPushButton" name="switch_view_button">
<widget class="SwitchViewButton" name="switch_view_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
......@@ -865,6 +865,11 @@ buttons below.</string>
<extends>QListView</extends>
<header>blink.sessions</header>
</customwidget>
<customwidget>
<class>SwitchViewButton</class>
<extends>QPushButton</extends>
<header>blink.widgets.buttons</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>search_box</tabstop>
......
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