Commit 4b90654f authored by Dan Pascu's avatar Dan Pascu

Simplified MWI code and improved its user interface

parent 056e27f6
......@@ -10,7 +10,7 @@ from functools import partial
from PyQt4 import uic
from PyQt4.QtCore import Qt, QUrl, QVariant
from PyQt4.QtGui import QAction, QActionGroup, QDesktopServices, QShortcut
from PyQt4.QtGui import QBrush, QColor, QFontMetrics, QPainter, QPen, QPixmap, QStyle, QStyleOptionComboBox, QStyleOptionFrameV2
from PyQt4.QtGui import QBrush, QColor, QFontMetrics, QIcon, QPainter, QPen, QPixmap, QStyle, QStyleOptionComboBox, QStyleOptionFrameV2
from application.notification import IObserver, NotificationCenter
from application.python.util import Null
......@@ -19,6 +19,7 @@ from zope.interface import implements
from sipsimple.account import Account, AccountManager, BonjourAccount
from sipsimple.application import SIPApplication
from sipsimple.configuration.settings import SIPSimpleSettings
from sipsimple.util import limit
from blink.aboutpanel import AboutPanel
from blink.accounts import AccountModel, ActiveAccountModel, AddAccountDialog, ServerToolsAccountModel, ServerToolsWindow
......@@ -42,6 +43,11 @@ class MainWindow(base_class, ui_class):
notification_center = NotificationCenter()
notification_center.add_observer(self, name='SIPApplicationWillStart')
notification_center.add_observer(self, name='SIPApplicationDidStart')
notification_center.add_observer(self, name='SIPAccountMWIDidGetSummary')
notification_center.add_observer(self, sender=AccountManager())
self.mwi_icons = [QIcon(Resources.get('icons/mwi-%d.png' % i)) for i in xrange(0, 11)]
self.mwi_icons.append(QIcon(Resources.get('icons/mwi-many.png')))
with Resources.directory:
self.setupUi()
......@@ -331,11 +337,9 @@ class MainWindow(base_class, ui_class):
self.server_tools_window.open_buy_pstn_access_page(account)
def _AH_VoicemailActionTriggered(self, action, checked):
account, received_voicemail_uri = action.data().toPyObject()
voicemail_uri = account.message_summary.voicemail_uri or received_voicemail_uri
if voicemail_uri:
session_manager = SessionManager()
session_manager.start_call(voicemail_uri, voicemail_uri, account=account)
account = action.data().toPyObject()
voicemail_uri = account.message_summary.uri
SessionManager().start_call("Voicemail", voicemail_uri, account=account)
def _SH_AddContactButtonClicked(self, clicked):
model = self.contact_model
......@@ -514,6 +518,7 @@ class MainWindow(base_class, ui_class):
handler(notification)
def _NH_SIPApplicationWillStart(self, notification):
account_manager = AccountManager()
settings = SIPSimpleSettings()
self.silent_action.setChecked(settings.audio.silent)
self.silent_button.setChecked(settings.audio.silent)
......@@ -522,28 +527,11 @@ class MainWindow(base_class, ui_class):
else:
self.google_contacts_action.setText(u'Disable Google Contacts')
self.google_contacts_action.triggered.connect(self._AH_GoogleContactsActionTriggered)
account_manager = AccountManager()
notification_center = NotificationCenter()
notification_center.add_observer(self, sender=account_manager)
if not any(account.enabled for account in account_manager.iter_accounts()):
self.display_name.setEnabled(False)
self.activity_note.setEnabled(False)
self.status.setEnabled(False)
self.status.setCurrentIndex(self.status.findText(u'Offline'))
for account in account_manager.iter_accounts():
action = QAction(account.id if account is not BonjourAccount() else u'Bonjour', None)
action.setCheckable(True)
action.setEnabled(True if account is not BonjourAccount() else BonjourAccount.mdns_available)
action.setData(QVariant(account))
action.setChecked(account.enabled)
action.triggered.connect(partial(self._AH_AccountActionTriggered, action))
self.accounts_menu.addAction(action)
if isinstance(account, Account) and account.enabled and account.message_summary.enabled:
vm_action = QAction(u'%s - No new messages' % account.id, None)
vm_action.setData(QVariant((account, None)))
vm_action.setEnabled(account.message_summary.voicemail_uri is not None)
vm_action.triggered.connect(partial(self._AH_VoicemailActionTriggered, vm_action))
self.voicemail_menu.addAction(vm_action)
def _NH_SIPApplicationDidStart(self, notification):
self.load_audio_devices()
......@@ -571,7 +559,6 @@ class MainWindow(base_class, ui_class):
settings.audio.input_device = new_device
settings.audio.output_device = new_device
settings.save()
# TODO: Add a confirmation window when no active sessions
self.load_audio_devices()
def _NH_CFGSettingsObjectDidChange(self, notification):
......@@ -602,53 +589,33 @@ class MainWindow(base_class, ui_class):
if 'enabled' in notification.data.modified:
action = (action for action in self.accounts_menu.actions() if action.data().toPyObject() is account).next()
action.setChecked(account.enabled)
if account.enabled and account.message_summary.enabled:
vm_action = QAction(u'%s - No new messages' % account.id, None)
vm_action.setData(QVariant((account, None)))
vm_action.setEnabled(account.message_summary.voicemail_uri is not None)
vm_action.triggered.connect(partial(self._AH_VoicemailActionTriggered, vm_action))
self.voicemail_menu.addAction(vm_action)
else:
try:
vm_action = (action for action in self.voicemail_menu.actions() if action.data().toPyObject()[0] is account).next()
except StopIteration:
pass
else:
self.voicemail_menu.removeAction(vm_action)
if 'message_summary.enabled' in notification.data.modified:
if account.message_summary.enabled:
vm_action = QAction(u'%s - No new messages' % account.id, None)
vm_action.setData(QVariant((account, None)))
vm_action.setEnabled(account.message_summary.voicemail_uri is not None)
vm_action.triggered.connect(partial(self._AH_VoicemailActionTriggered, vm_action))
self.voicemail_menu.addAction(vm_action)
else:
vm_action = (action for action in self.voicemail_menu.actions() if action.data().toPyObject()[0] is account).next()
self.voicemail_menu.removeAction(action)
if 'message_summary.voicemail_uri' in notification.data.modified:
if account.message_summary.enabled:
vm_action = (action for action in self.voicemail_menu.actions() if action.data().toPyObject()[0] is account).next()
vm_action.setEnabled(account.message_summary.voicemail_uri is not None)
def _NH_SIPAccountManagerWillStart(self, notification):
notification_center = NotificationCenter()
notification_center.add_observer(self, name='SIPAccountMWIDidGetSummary')
if set(['enabled', 'message_summary.enabled', 'message_summary.voicemail_uri']).intersection(notification.data.modified):
action = (action for action in self.voicemail_menu.actions() if action.data().toPyObject() is account).next()
action.setVisible(False if account is BonjourAccount() else account.enabled and account.message_summary.enabled)
action.setEnabled(False if account is BonjourAccount() else account.message_summary.uri is not None)
def _NH_SIPAccountManagerDidAddAccount(self, notification):
account = notification.data.account
action = QAction(account.id, None)
action = QAction(account.id if account is not BonjourAccount() else u'Bonjour', None)
action.setEnabled(True if account is not BonjourAccount() else BonjourAccount.mdns_available)
action.setCheckable(True)
action.setChecked(account.enabled)
action.setData(QVariant(account))
action.triggered.connect(partial(self._AH_AccountActionTriggered, action))
self.accounts_menu.addAction(action)
action = QAction(self.mwi_icons[0], account.id, None)
action.setVisible(False if account is BonjourAccount() else account.enabled and account.message_summary.enabled)
action.setEnabled(False if account is BonjourAccount() else account.message_summary.uri is not None)
action.setData(QVariant(account))
action.triggered.connect(partial(self._AH_VoicemailActionTriggered, action))
self.voicemail_menu.addAction(action)
def _NH_SIPAccountManagerDidRemoveAccount(self, notification):
account = notification.data.account
action = (action for action in self.accounts_menu.actions() if action.data().toPyObject() is account).next()
self.accounts_menu.removeAction(action)
if isinstance(account, Account) and account.enabled and account.message_summary.enabled:
action = (action for action in self.voicemail_menu.actions() if action.data().toPyObject()[0] is account).next()
self.voicemail_menu.removeAction(action)
action = (action for action in self.voicemail_menu.actions() if action.data().toPyObject() is account).next()
self.voicemail_menu.removeAction(action)
def _NH_SIPAccountManagerDidChangeDefaultAccount(self, notification):
if notification.data.account is None:
......@@ -660,15 +627,16 @@ class MainWindow(base_class, ui_class):
def _NH_SIPAccountMWIDidGetSummary(self, notification):
account = notification.sender
summary = notification.data.message_summary
action = (action for action in self.voicemail_menu.actions() if action.data().toPyObject()[0] is account).next()
action.setData(QVariant((account, summary.message_account)))
action.setEnabled(True if account.message_summary.voicemail_uri is not None or summary.message_account is not None else False)
if summary.messages_waiting and summary.summaries.get('voice-message') is not None:
new_messages = int(summary.summaries.get('voice-message').get('new_messages', 0))
vm_text = u'%d new messages' % new_messages if new_messages > 0 else u'No new messages'
action = (action for action in self.voicemail_menu.actions() if action.data().toPyObject() is account).next()
action.setEnabled(account.message_summary.uri is not None)
if summary.messages_waiting:
try:
new_messages = limit(int(summary.summaries['voice-message']['new_messages']), min=0, max=11)
except (KeyError, ValueError):
new_messages = 0
else:
vm_text = u'No new messages'
action.setText(u'%s - %s' % (account.id, vm_text))
new_messages = 0
action.setIcon(self.mwi_icons[new_messages])
del ui_class, base_class
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16px"
height="16px"
id="svg2816"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="drawing-1.png">
<defs
id="defs2818">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 8 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="16 : 8 : 1"
inkscape:persp3d-origin="8 : 5.3333333 : 1"
id="perspective2824" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8.7173008"
inkscape:cx="38.878553"
inkscape:cy="12.659164"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1209"
inkscape:window-height="763"
inkscape:window-x="367"
inkscape:window-y="230"
inkscape:window-maximized="0" />
<metadata
id="metadata2821">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
sodipodi:type="arc"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#c70000;stroke-width:0.99800003;stroke-linecap:butt;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path2826"
sodipodi:cx="10.316337"
sodipodi:cy="10.07599"
sodipodi:rx="5.6762376"
sodipodi:ry="6.0141091"
d="m 15.992574,10.07599 a 5.6762376,6.0141091 0 1 1 -11.352475,0 5.6762376,6.0141091 0 1 1 11.352475,0 z"
transform="matrix(1.2984867,0,0,1.2255379,-5.3956259,-4.3485073)" />
<text
xml:space="preserve"
style="font-size:9.39675713px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Trebuchet MS;-inkscape-font-specification:Trebuchet MS"
x="1.8998702"
y="10.112906"
id="text3600"
transform="scale(0.84227997,1.1872537)"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3602"
x="1.8998702"
y="10.112906">999</tspan></text>
</g>
</svg>
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