Commit e6145b72 authored by Dan Pascu's avatar Dan Pascu

Modernized code and improved PEP-8 compliance

parent 8c6e300f
# #
# Boring file regular expresions # Boring file regular expressions
# #
~$ ~$
......
__all__ = ['Blink']
__version__ = '1.4.2' __version__ = '1.4.2'
__date__ = 'December 4th 2015' __date__ = 'December 4th 2015'
import os import os
import sys import sys
import sip import sip
...@@ -42,6 +38,7 @@ try: ...@@ -42,6 +38,7 @@ try:
from blink import branding from blink import branding
except ImportError: except ImportError:
branding = Null branding = Null
from blink.chatwindow import ChatWindow from blink.chatwindow import ChatWindow
from blink.configuration.account import AccountExtension, BonjourAccountExtension from blink.configuration.account import AccountExtension, BonjourAccountExtension
from blink.configuration.addressbook import ContactExtension, GroupExtension from blink.configuration.addressbook import ContactExtension, GroupExtension
...@@ -56,6 +53,9 @@ from blink.update import UpdateManager ...@@ -56,6 +53,9 @@ from blink.update import UpdateManager
from blink.util import QSingleton, run_in_gui_thread from blink.util import QSingleton, run_in_gui_thread
__all__ = ['Blink']
if hasattr(sys, 'frozen'): if hasattr(sys, 'frozen'):
output = sys.stdout output = sys.stdout
makedirs(ApplicationData.get('logs')) makedirs(ApplicationData.get('logs'))
...@@ -293,7 +293,7 @@ class Blink(QApplication): ...@@ -293,7 +293,7 @@ class Blink(QApplication):
self.main_window.show() self.main_window.show()
settings = SIPSimpleSettings() settings = SIPSimpleSettings()
accounts = AccountManager().get_accounts() accounts = AccountManager().get_accounts()
if not accounts or (self.first_run and accounts==[BonjourAccount()]): if not accounts or (self.first_run and accounts == [BonjourAccount()]):
self.main_window.preferences_window.show_create_account_dialog() self.main_window.preferences_window.show_create_account_dialog()
if settings.google_contacts.authorization_token is InvalidToken: if settings.google_contacts.authorization_token is InvalidToken:
self.main_window.google_contacts_dialog.open_for_incorrect_password() self.main_window.google_contacts_dialog.open_for_incorrect_password()
......
__all__ = ['AboutPanel']
from PyQt4 import uic from PyQt4 import uic
from blink import __date__, __version__ from blink import __date__, __version__
...@@ -8,6 +6,9 @@ from blink.resources import Resources ...@@ -8,6 +6,9 @@ from blink.resources import Resources
from blink.util import QSingleton from blink.util import QSingleton
__all__ = ['AboutPanel']
credits_text = """ credits_text = """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html> <html>
...@@ -32,6 +33,7 @@ credits_text = """ ...@@ -32,6 +33,7 @@ credits_text = """
ui_class, base_class = uic.loadUiType(Resources.get('about_panel.ui')) ui_class, base_class = uic.loadUiType(Resources.get('about_panel.ui'))
class AboutPanel(base_class, ui_class): class AboutPanel(base_class, ui_class):
__metaclass__ = QSingleton __metaclass__ = QSingleton
...@@ -43,16 +45,16 @@ class AboutPanel(base_class, ui_class): ...@@ -43,16 +45,16 @@ class AboutPanel(base_class, ui_class):
self.version.setText(u'Version %s\n%s' % (__version__, __date__)) self.version.setText(u'Version %s\n%s' % (__version__, __date__))
credits_width = self.credits_text.fontMetrics().width("NLNET Foundation" + "http://sipsimpleclient.org") + 40 credits_width = self.credits_text.fontMetrics().width("NLnet Foundation" + "http://sipsimpleclient.org") + 40
self.credits_text.setFixedWidth(credits_width) self.credits_text.setFixedWidth(credits_width)
self.credits_text.document().documentLayout().documentSizeChanged.connect(self._credits_size_changed) self.credits_text.document().documentLayout().documentSizeChanged.connect(self._credits_size_changed)
self.credits_text.setHtml(credits_text) self.credits_text.setHtml(credits_text)
def _credits_size_changed(self, size): def _credits_size_changed(self, size):
self.credits_text.document().documentLayout().documentSizeChanged.disconnect(self._credits_size_changed) self.credits_text.document().documentLayout().documentSizeChanged.disconnect(self._credits_size_changed)
self.setFixedSize(self.minimumSize().width(), self.minimumSize().width()*1.40) # set a fixed aspect ratio self.setFixedSize(self.minimumSize().width(), self.minimumSize().width()*1.40) # set a fixed aspect ratio
row_height = self.credits_text.fontMetrics().height() + 2 # +2 for cellspacing row_height = self.credits_text.fontMetrics().height() + 2 # +2 for cellspacing
max_credits_height = 8*row_height + 2 + 14 # allow for maximum 8 rows; +2 for cellspacing and +14 for top/bottom margins max_credits_height = 8*row_height + 2 + 14 # allow for maximum 8 rows; +2 for cellspacing and +14 for top/bottom margins
if self.credits_text.height() > max_credits_height: if self.credits_text.height() > max_credits_height:
self.setFixedHeight(self.height() - (self.credits_text.height() - max_credits_height)) self.setFixedHeight(self.height() - (self.credits_text.height() - max_credits_height))
......
__all__ = ['AccountModel', 'ActiveAccountModel', 'AccountSelector', 'AddAccountDialog', 'ServerToolsAccountModel', 'ServerToolsWindow']
import os import os
import re import re
import sys import sys
...@@ -10,9 +8,9 @@ from collections import defaultdict ...@@ -10,9 +8,9 @@ from collections import defaultdict
from PyQt4 import uic from PyQt4 import uic
from PyQt4.QtCore import Qt, QAbstractListModel, QModelIndex, QUrl from PyQt4.QtCore import Qt, QAbstractListModel, QModelIndex, QUrl
from PyQt4.QtGui import QAction, QButtonGroup, QComboBox, QIcon, QMenu, QMovie, QSortFilterProxyModel from PyQt4.QtGui import QAction, QButtonGroup, QComboBox, QIcon, QMenu, QMovie, QSortFilterProxyModel
from PyQt4.QtNetwork import QNetworkAccessManager from PyQt4.QtNetwork import QNetworkAccessManager
from PyQt4.QtWebKit import QWebView from PyQt4.QtWebKit import QWebView
import cjson import cjson
from application.notification import IObserver, NotificationCenter from application.notification import IObserver, NotificationCenter
...@@ -31,17 +29,23 @@ from blink.widgets.labels import Status ...@@ -31,17 +29,23 @@ from blink.widgets.labels import Status
from blink.util import QSingleton, call_in_gui_thread, run_in_gui_thread from blink.util import QSingleton, call_in_gui_thread, run_in_gui_thread
__all__ = ['AccountModel', 'ActiveAccountModel', 'AccountSelector', 'AddAccountDialog', 'ServerToolsAccountModel', 'ServerToolsWindow']
class IconDescriptor(object): class IconDescriptor(object):
def __init__(self, filename): def __init__(self, filename):
self.filename = filename self.filename = filename
self.icon = None self.icon = None
def __get__(self, obj, objtype):
def __get__(self, instance, owner):
if self.icon is None: if self.icon is None:
self.icon = QIcon(self.filename) self.icon = QIcon(self.filename)
self.icon.filename = self.filename self.icon.filename = self.filename
return self.icon return self.icon
def __set__(self, obj, value): def __set__(self, obj, value):
raise AttributeError("attribute cannot be set") raise AttributeError("attribute cannot be set")
def __delete__(self, obj): def __delete__(self, obj):
raise AttributeError("attribute cannot be deleted") raise AttributeError("attribute cannot be deleted")
...@@ -222,6 +226,7 @@ class AccountSelector(QComboBox): ...@@ -222,6 +226,7 @@ class AccountSelector(QComboBox):
ui_class, base_class = uic.loadUiType(Resources.get('add_account.ui')) ui_class, base_class = uic.loadUiType(Resources.get('add_account.ui'))
class AddAccountDialog(base_class, ui_class): class AddAccountDialog(base_class, ui_class):
__metaclass__ = QSingleton __metaclass__ = QSingleton
...@@ -241,9 +246,9 @@ class AddAccountDialog(base_class, ui_class): ...@@ -241,9 +246,9 @@ class AddAccountDialog(base_class, ui_class):
font.setFamily("Sans Serif") font.setFamily("Sans Serif")
self.title_label.setFont(font) self.title_label.setFont(font)
font_metrics = self.create_status_label.fontMetrics() font_metrics = self.create_status_label.fontMetrics()
self.create_status_label.setMinimumHeight(font_metrics.height() + 2*(font_metrics.height() + font_metrics.leading())) # reserve space for 3 lines self.create_status_label.setMinimumHeight(font_metrics.height() + 2*(font_metrics.height() + font_metrics.leading())) # reserve space for 3 lines
font_metrics = self.email_note_label.fontMetrics() font_metrics = self.email_note_label.fontMetrics()
self.email_note_label.setMinimumWidth(font_metrics.width(u'The E-mail address is used when sending voicemail')) # hack to make text justification look nice everywhere self.email_note_label.setMinimumWidth(font_metrics.width(u'The E-mail address is used when sending voicemail')) # hack to make text justification look nice everywhere
self.add_account_button.setChecked(True) self.add_account_button.setChecked(True)
self.panel_view.setCurrentWidget(self.add_account_panel) self.panel_view.setCurrentWidget(self.add_account_panel)
self.new_password_editor.textChanged.connect(self._SH_PasswordTextChanged) self.new_password_editor.textChanged.connect(self._SH_PasswordTextChanged)
...@@ -259,7 +264,7 @@ class AddAccountDialog(base_class, ui_class): ...@@ -259,7 +264,7 @@ class AddAccountDialog(base_class, ui_class):
self.email_address_editor.statusChanged.connect(self._SH_ValidityStatusChanged) self.email_address_editor.statusChanged.connect(self._SH_ValidityStatusChanged)
self.display_name_editor.regexp = re.compile('^.*$') self.display_name_editor.regexp = re.compile('^.*$')
self.name_editor.regexp = re.compile('^.+$') self.name_editor.regexp = re.compile('^.+$')
self.username_editor.regexp = re.compile('^\w(?<=[^0_])[\w.-]{4,31}(?<=[^_.-])$', re.IGNORECASE) # in order to enable unicode characters add re.UNICODE to flags self.username_editor.regexp = re.compile('^\w(?<=[^0_])[\w.-]{4,31}(?<=[^_.-])$', re.IGNORECASE) # in order to enable unicode characters add re.UNICODE to flags
self.sip_address_editor.regexp = re.compile('^[^@\s]+@[^@\s]+$') self.sip_address_editor.regexp = re.compile('^[^@\s]+@[^@\s]+$')
self.password_editor.regexp = re.compile('^.*$') self.password_editor.regexp = re.compile('^.*$')
self.new_password_editor.regexp = re.compile('^.{8,}$') self.new_password_editor.regexp = re.compile('^.{8,}$')
...@@ -587,6 +592,7 @@ class ServerToolsWebView(QWebView): ...@@ -587,6 +592,7 @@ class ServerToolsWebView(QWebView):
ui_class, base_class = uic.loadUiType(Resources.get('server_tools.ui')) ui_class, base_class = uic.loadUiType(Resources.get('server_tools.ui'))
class ServerToolsWindow(base_class, ui_class): class ServerToolsWindow(base_class, ui_class):
__metaclass__ = QSingleton __metaclass__ = QSingleton
...@@ -599,7 +605,7 @@ class ServerToolsWindow(base_class, ui_class): ...@@ -599,7 +605,7 @@ class ServerToolsWindow(base_class, ui_class):
self.spinner_label.hide() self.spinner_label.hide()
self.progress_bar.hide() self.progress_bar.hide()
while self.tab_widget.count(): while self.tab_widget.count():
self.tab_widget.removeTab(0) # remove the tab(s) added in designer self.tab_widget.removeTab(0) # remove the tab(s) added in designer
self.tab_widget.tabBar().hide() self.tab_widget.tabBar().hide()
self.account_button.setMenu(QMenu(self.account_button)) self.account_button.setMenu(QMenu(self.account_button))
self.setWindowTitle('Blink Server Tools') self.setWindowTitle('Blink Server Tools')
...@@ -629,7 +635,7 @@ class ServerToolsWindow(base_class, ui_class): ...@@ -629,7 +635,7 @@ class ServerToolsWindow(base_class, ui_class):
self.spinner_label.show() self.spinner_label.show()
self.spinner_movie.start() self.spinner_movie.start()
self.progress_bar.setValue(0) self.progress_bar.setValue(0)
#self.progress_bar.show() # self.progress_bar.show()
def _SH_WebViewLoadFinished(self, load_ok): def _SH_WebViewLoadFinished(self, load_ok):
self.spinner_movie.stop() self.spinner_movie.stop()
......
This diff is collapsed.
...@@ -176,7 +176,7 @@ class IconDescriptor(object): ...@@ -176,7 +176,7 @@ class IconDescriptor(object):
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, IconDescriptor): if isinstance(other, IconDescriptor):
return self.url==other.url and self.etag==other.etag return self.url == other.url and self.etag == other.etag
return NotImplemented return NotImplemented
def __ne__(self, other): def __ne__(self, other):
...@@ -208,7 +208,7 @@ class PresenceState(object): ...@@ -208,7 +208,7 @@ class PresenceState(object):
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, PresenceState): if isinstance(other, PresenceState):
return self.state==other.state and self.note==other.note return self.state == other.state and self.note == other.note
return NotImplemented return NotImplemented
def __ne__(self, other): def __ne__(self, other):
......
...@@ -83,7 +83,7 @@ class SIPSimpleSettingsExtension(SettingsObjectExtension): ...@@ -83,7 +83,7 @@ class SIPSimpleSettingsExtension(SettingsObjectExtension):
sounds = SoundSettings sounds = SoundSettings
tls = TLSSettingsExtension tls = TLSSettingsExtension
user_agent = Setting(type=str, default='Blink %s (%s)' % (__version__, platform.system() if sys.platform!='darwin' else 'MacOSX Qt')) user_agent = Setting(type=str, default='Blink %s (%s)' % (__version__, platform.system() if sys.platform != 'darwin' else 'MacOSX Qt'))
class SessionInfoSettings(SettingsGroup): class SessionInfoSettings(SettingsGroup):
......
This diff is collapsed.
__all__ = ['CallFunctionEvent']
from PyQt4.QtCore import QEvent from PyQt4.QtCore import QEvent
from application.python.descriptor import classproperty from application.python.descriptor import classproperty
__all__ = ['CallFunctionEvent']
class EventMeta(type(QEvent)): class EventMeta(type(QEvent)):
def __init__(cls, name, bases, dct): def __init__(cls, name, bases, dct):
super(EventMeta, cls).__init__(name, bases, dct) super(EventMeta, cls).__init__(name, bases, dct)
...@@ -35,4 +36,3 @@ class CallFunctionEvent(EventBase): ...@@ -35,4 +36,3 @@ class CallFunctionEvent(EventBase):
self.args = args self.args = args
self.kw = kw self.kw = kw
__all__ = ['FileTransferWindow']
import os import os
from PyQt4 import uic from PyQt4 import uic
...@@ -18,8 +16,12 @@ from blink.sessions import FileTransferDelegate, FileTransferModel ...@@ -18,8 +16,12 @@ from blink.sessions import FileTransferDelegate, FileTransferModel
from blink.widgets.util import ContextMenuActions from blink.widgets.util import ContextMenuActions
__all__ = ['FileTransferWindow']
ui_class, base_class = uic.loadUiType(Resources.get('filetransfer_window.ui')) ui_class, base_class = uic.loadUiType(Resources.get('filetransfer_window.ui'))
class FileTransferWindow(base_class, ui_class): class FileTransferWindow(base_class, ui_class):
implements(IObserver) implements(IObserver)
...@@ -63,7 +65,7 @@ class FileTransferWindow(base_class, ui_class): ...@@ -63,7 +65,7 @@ class FileTransferWindow(base_class, ui_class):
def update_status(self): def update_status(self):
total = len(self.model.items) total = len(self.model.items)
active = len([item for item in self.model.items if not item.ended]) active = len([item for item in self.model.items if not item.ended])
text = u'%d %s' % (total, 'transfer' if total==1 else 'transfers') text = u'%d %s' % (total, 'transfer' if total == 1 else 'transfers')
if active > 0: if active > 0:
text += u' (%d active)' % active text += u' (%d active)' % active
self.status_label.setText(text) self.status_label.setText(text)
......
__all__ = ['HistoryManager']
import bisect import bisect
import cPickle as pickle import cPickle as pickle
import re import re
...@@ -23,6 +21,9 @@ from blink.resources import ApplicationData, Resources ...@@ -23,6 +21,9 @@ from blink.resources import ApplicationData, Resources
from blink.util import run_in_gui_thread from blink.util import run_in_gui_thread
__all__ = ['HistoryManager']
class HistoryManager(object): class HistoryManager(object):
__metaclass__ = Singleton __metaclass__ = Singleton
implements(IObserver) implements(IObserver)
...@@ -86,13 +87,16 @@ class IconDescriptor(object): ...@@ -86,13 +87,16 @@ class IconDescriptor(object):
def __init__(self, filename): def __init__(self, filename):
self.filename = filename self.filename = filename
self.icon = None self.icon = None
def __get__(self, obj, objtype):
def __get__(self, instance, owner):
if self.icon is None: if self.icon is None:
self.icon = QIcon(self.filename) self.icon = QIcon(self.filename)
self.icon.filename = self.filename self.icon.filename = self.filename
return self.icon return self.icon
def __set__(self, obj, value): def __set__(self, obj, value):
raise AttributeError("attribute cannot be set") raise AttributeError("attribute cannot be set")
def __delete__(self, obj): def __delete__(self, obj):
raise AttributeError("attribute cannot be deleted") raise AttributeError("attribute cannot be deleted")
...@@ -116,7 +120,7 @@ class HistoryEntry(object): ...@@ -116,7 +120,7 @@ class HistoryEntry(object):
self.reason = reason self.reason = reason
def __reduce__(self): def __reduce__(self):
return (self.__class__, (self.direction, self.name, self.uri, self.account_id, self.call_time, self.duration, self.failed, self.reason)) return self.__class__, (self.direction, self.name, self.uri, self.account_id, self.call_time, self.duration, self.failed, self.reason)
def __eq__(self, other): def __eq__(self, other):
return self is other return self is other
...@@ -174,7 +178,7 @@ class HistoryEntry(object): ...@@ -174,7 +178,7 @@ class HistoryEntry(object):
@classmethod @classmethod
def from_session(cls, session): def from_session(cls, session):
if session.start_time is None and session.end_time is not None: if session.start_time is None and session.end_time is not None:
# Session may have anded before it fully started # Session may have ended before it fully started
session.start_time = session.end_time session.start_time = session.end_time
call_time = session.start_time or ISOTimestamp.now() call_time = session.start_time or ISOTimestamp.now()
if session.start_time and session.end_time: if session.start_time and session.end_time:
......
__all__ = ['LogManager']
import os import os
import sys import sys
...@@ -21,6 +19,9 @@ from sipsimple.configuration.settings import SIPSimpleSettings ...@@ -21,6 +19,9 @@ from sipsimple.configuration.settings import SIPSimpleSettings
from blink.resources import ApplicationData from blink.resources import ApplicationData
__all__ = ['LogManager']
class NotificationQueue(object): class NotificationQueue(object):
implements(IObserver) implements(IObserver)
...@@ -161,10 +162,10 @@ class LogManager(object): ...@@ -161,10 +162,10 @@ class LogManager(object):
direction = "RECEIVED" direction = "RECEIVED"
else: else:
direction = "SENDING" direction = "SENDING"
buf = ["%s: Packet %d, +%s" % (direction, self._siptrace_packet_count, (notification.datetime - self._siptrace_start_time))] buf = ["%s: Packet %d, +%s" % (direction, self._siptrace_packet_count, (notification.datetime - self._siptrace_start_time)),
buf.append("%(source_ip)s:%(source_port)d -(SIP over %(transport)s)-> %(destination_ip)s:%(destination_port)d" % notification.data.__dict__) "%(source_ip)s:%(source_port)d -(SIP over %(transport)s)-> %(destination_ip)s:%(destination_port)d" % notification.data.__dict__,
buf.append(notification.data.data) notification.data.data,
buf.append('--') '--']
message = '\n'.join(buf) message = '\n'.join(buf)
try: try:
self.siptrace_file.write('%s [%s %d]: %s\n' % (notification.datetime, self.name, self.pid, message)) self.siptrace_file.write('%s [%s %d]: %s\n' % (notification.datetime, self.name, self.pid, message))
...@@ -236,4 +237,3 @@ class LogManager(object): ...@@ -236,4 +237,3 @@ class LogManager(object):
except Exception: except Exception:
pass pass
This diff is collapsed.
This diff is collapsed.
__all__ = ['PresenceManager', 'PendingWatcherDialog']
import base64 import base64
import hashlib import hashlib
import re import re
...@@ -36,6 +34,9 @@ from blink.resources import IconManager, Resources ...@@ -36,6 +34,9 @@ from blink.resources import IconManager, Resources
from blink.util import run_in_gui_thread from blink.util import run_in_gui_thread
__all__ = ['PresenceManager', 'PendingWatcherDialog']
epoch = datetime.fromtimestamp(0, tzutc()) epoch = datetime.fromtimestamp(0, tzutc())
...@@ -50,7 +51,7 @@ class BlinkPresenceState(object): ...@@ -50,7 +51,7 @@ class BlinkPresenceState(object):
state = blink_settings.presence.current_state.state state = blink_settings.presence.current_state.state
note = blink_settings.presence.current_state.note note = blink_settings.presence.current_state.note
state = 'offline' if state=='Invisible' else state.lower() state = 'offline' if state == 'Invisible' else state.lower()
if self.account is BonjourAccount(): if self.account is BonjourAccount():
return BonjourPresenceState(state, note) return BonjourPresenceState(state, note)
...@@ -182,10 +183,10 @@ class PresencePublicationHandler(object): ...@@ -182,10 +183,10 @@ class PresencePublicationHandler(object):
account.presence_state = BlinkPresenceState(account).online_state account.presence_state = BlinkPresenceState(account).online_state
else: else:
account = notification.sender account = notification.sender
if set(['xcap.enabled', 'xcap.xcap_root']).intersection(notification.data.modified): if {'xcap.enabled', 'xcap.xcap_root'}.intersection(notification.data.modified):
account.xcap.icon = None account.xcap.icon = None
account.save() account.save()
elif set(['presence.enabled', 'display_name', 'xcap.icon']).intersection(notification.data.modified) and account.presence.enabled: elif {'presence.enabled', 'display_name', 'xcap.icon'}.intersection(notification.data.modified) and account.presence.enabled:
account.presence_state = BlinkPresenceState(account).online_state account.presence_state = BlinkPresenceState(account).online_state
def _NH_SIPAccountWillActivate(self, notification): def _NH_SIPAccountWillActivate(self, notification):
...@@ -219,11 +220,11 @@ class PresencePublicationHandler(object): ...@@ -219,11 +220,11 @@ class PresencePublicationHandler(object):
blink_settings.presence.current_state = new_state blink_settings.presence.current_state = new_state
if new_state.note: if new_state.note:
try: try:
next(state for state in blink_settings.presence.state_history if state==new_state) next(state for state in blink_settings.presence.state_history if state == new_state)
except StopIteration: except StopIteration:
blink_settings.presence.state_history = [new_state] + blink_settings.presence.state_history blink_settings.presence.state_history = [new_state] + blink_settings.presence.state_history
else: else:
blink_settings.presence.state_history = [new_state] + [state for state in blink_settings.presence.state_history if state!=new_state] blink_settings.presence.state_history = [new_state] + [state for state in blink_settings.presence.state_history if state != new_state]
blink_settings.save() blink_settings.save()
def _NH_SIPAccountDidDiscoverXCAPSupport(self, notification): def _NH_SIPAccountDidDiscoverXCAPSupport(self, notification):
...@@ -334,11 +335,11 @@ class PresenceSubscriptionHandler(object): ...@@ -334,11 +335,11 @@ class PresenceSubscriptionHandler(object):
def service_sort_key(service): def service_sort_key(service):
timestamp = service.timestamp.value if service.timestamp else epoch timestamp = service.timestamp.value if service.timestamp else epoch
if service.status.extended is not None: if service.status.extended is not None:
return (100, timestamp) return 100, timestamp
elif service.status.basic == 'open': elif service.status.basic == 'open':
return (10, timestamp) return 10, timestamp
else: else:
return (0, timestamp) return 0, timestamp
current_pidf_map = {} current_pidf_map = {}
contact_pidf_map = {} contact_pidf_map = {}
...@@ -365,7 +366,7 @@ class PresenceSubscriptionHandler(object): ...@@ -365,7 +366,7 @@ class PresenceSubscriptionHandler(object):
if service.status.extended: if service.status.extended:
state = unicode(service.status.extended) state = unicode(service.status.extended)
else: else:
state = 'available' if service.status.basic=='open' else 'offline' state = 'available' if service.status.basic == 'open' else 'offline'
note = unicode(next(iter(service.notes))) if service.notes else None note = unicode(next(iter(service.notes))) if service.notes else None
icon_url = unicode(service.icon) if service.icon else None icon_url = unicode(service.icon) if service.icon else None
...@@ -406,7 +407,7 @@ class PresenceSubscriptionHandler(object): ...@@ -406,7 +407,7 @@ class PresenceSubscriptionHandler(object):
self._winfo_map.pop(old_id, None) self._winfo_map.pop(old_id, None)
self._process_presence_data() self._process_presence_data()
return return
if set(['enabled', 'presence.enabled']).intersection(notification.data.modified): if {'enabled', 'presence.enabled'}.intersection(notification.data.modified):
if not account.enabled or not account.presence.enabled: if not account.enabled or not account.presence.enabled:
self._pidf_map.pop(account.id, None) self._pidf_map.pop(account.id, None)
self._winfo_map.pop(account.id, None) self._winfo_map.pop(account.id, None)
......
"""Provide access to Blink's resources""" """Provide access to Blink's resources"""
__all__ = ['ApplicationData', 'Resources', 'IconManager']
import __main__ import __main__
import imghdr import imghdr
import os import os
...@@ -21,10 +19,14 @@ from sipsimple.configuration.datatypes import Path ...@@ -21,10 +19,14 @@ from sipsimple.configuration.datatypes import Path
from blink.util import run_in_gui_thread from blink.util import run_in_gui_thread
__all__ = ['ApplicationData', 'Resources', 'IconManager']
class DirectoryContextManager(unicode): class DirectoryContextManager(unicode):
def __enter__(self): def __enter__(self):
self.directory = os.getcwdu() self.directory = os.getcwdu()
os.chdir(self) os.chdir(self)
def __exit__(self, type, value, traceback): def __exit__(self, type, value, traceback):
os.chdir(self.directory) os.chdir(self.directory)
......
__all__ = ['ScreensharingWindow', 'VNCViewer', 'VNCClient', 'RFBSettings', 'ServerDefault', 'TrueColor', 'HighColor', 'LowColor']
from blink.screensharing.vncclient import VNCClient, RFBSettings, ServerDefault, TrueColor, HighColor, LowColor from blink.screensharing.vncclient import VNCClient, RFBSettings, ServerDefault, TrueColor, HighColor, LowColor
from blink.screensharing.vncviewer import ScreensharingWindow, VNCViewer from blink.screensharing.vncviewer import ScreensharingWindow, VNCViewer
__all__ = ['ScreensharingWindow', 'VNCViewer', 'VNCClient', 'RFBSettings', 'ServerDefault', 'TrueColor', 'HighColor', 'LowColor']
__all__ = ['RFBClient', 'RFBClientError']
from sip import voidptr from sip import voidptr
from PyQt4.QtCore import QThread from PyQt4.QtCore import QThread
from PyQt4.QtGui import QImage from PyQt4.QtGui import QImage
...@@ -12,6 +10,9 @@ from libc.stdlib cimport calloc, malloc, free ...@@ -12,6 +10,9 @@ from libc.stdlib cimport calloc, malloc, free
from libc.string cimport memcpy, strlen from libc.string cimport memcpy, strlen
__all__ = ['RFBClient', 'RFBClientError']
# external declarations # external declarations
# #
......
__all__ = ['VNCClient', 'RFBSettings', 'ServerDefault', 'TrueColor', 'HighColor', 'LowColor']
from PyQt4.QtCore import QObject, QSize, QSocketNotifier, QThread, pyqtSignal from PyQt4.QtCore import QObject, QSize, QSocketNotifier, QThread, pyqtSignal
from PyQt4.QtGui import QApplication from PyQt4.QtGui import QApplication
...@@ -10,7 +7,10 @@ from application.python import Null ...@@ -10,7 +7,10 @@ from application.python import Null
from application.python.descriptor import WriteOnceAttribute from application.python.descriptor import WriteOnceAttribute
from blink.event import EventBase from blink.event import EventBase
from blink.screensharing._rfb import RFBClient, RFBClientError from blink.screensharing._rfb import RFBClient, RFBClientError
__all__ = ['VNCClient', 'RFBSettings', 'ServerDefault', 'TrueColor', 'HighColor', 'LowColor']
class RFBSettings(object): class RFBSettings(object):
...@@ -101,6 +101,7 @@ class VNCClient(QObject): ...@@ -101,6 +101,7 @@ class VNCClient(QObject):
def _get_settings(self): def _get_settings(self):
return self.__dict__['settings'] return self.__dict__['settings']
def _set_settings(self, settings): def _set_settings(self, settings):
old_settings = self.__dict__.get('settings', None) old_settings = self.__dict__.get('settings', None)
if settings == old_settings: if settings == old_settings:
...@@ -108,6 +109,7 @@ class VNCClient(QObject): ...@@ -108,6 +109,7 @@ class VNCClient(QObject):
self.__dict__['settings'] = settings self.__dict__['settings'] = settings
if self.thread.isRunning(): if self.thread.isRunning():
QApplication.postEvent(self, RFBConfigureClientEvent()) QApplication.postEvent(self, RFBConfigureClientEvent())
settings = property(_get_settings, _set_settings) settings = property(_get_settings, _set_settings)
del _get_settings, _set_settings del _get_settings, _set_settings
......
This diff is collapsed.
This diff is collapsed.
__all__ = ['IUpdateManager', 'UpdateManager']
import sys import sys
from application.python import Null from application.python import Null
from zope.interface import Interface from zope.interface import Interface
__all__ = ['IUpdateManager', 'UpdateManager']
class IUpdateManager(Interface): class IUpdateManager(Interface):
def initialize(self): def initialize(self):
pass pass
def shutdown(self): def shutdown(self):
pass pass
def check_for_updates(self): def check_for_updates(self):
pass pass
...@@ -23,4 +26,3 @@ if sys.platform == 'win32': ...@@ -23,4 +26,3 @@ if sys.platform == 'win32':
UpdateManager = Null UpdateManager = Null
else: else:
UpdateManager = Null UpdateManager = Null
...@@ -19,14 +19,13 @@ def library_locations(name): ...@@ -19,14 +19,13 @@ def library_locations(name):
for path in additional_paths: for path in additional_paths:
yield os.path.join(path, library_name) yield os.path.join(path, library_name)
def load_library(name): def load_library(name):
for library in library_locations(name): for library in library_locations(name):
try: try:
return CDLL(library) return CDLL(library)
except OSError: except OSError:
pass pass
else:
break
else: else:
raise RuntimeError('cannot find %s on this system' % name) raise RuntimeError('cannot find %s on this system' % name)
......
__all__ = ['QSingleton', 'call_in_gui_thread', 'call_later', 'run_in_gui_thread']
from PyQt4.QtCore import QObject, QThread, QTimer from PyQt4.QtCore import QObject, QThread, QTimer
from PyQt4.QtGui import QApplication from PyQt4.QtGui import QApplication
from application.python.decorator import decorator, preserve_signature from application.python.decorator import decorator, preserve_signature
...@@ -9,6 +7,9 @@ from application.python.types import Singleton ...@@ -9,6 +7,9 @@ from application.python.types import Singleton
from blink.event import CallFunctionEvent from blink.event import CallFunctionEvent
__all__ = ['QSingleton', 'call_in_gui_thread', 'call_later', 'run_in_gui_thread']
class QSingleton(Singleton, type(QObject)): class QSingleton(Singleton, type(QObject)):
"""A metaclass for making Qt objects singletons""" """A metaclass for making Qt objects singletons"""
......
__all__ = ['ToolButton', 'ConferenceButton', 'StreamButton', 'SegmentButton', 'SingleSegment', 'LeftSegment', 'MiddleSegment', 'RightSegment', 'RecordButton', 'SwitchViewButton',
'StateButton', 'AccountState']
from PyQt4.QtCore import Qt, QLineF, QPointF, QRectF, QSize, QTimer, pyqtSignal, pyqtSignature from PyQt4.QtCore import Qt, QLineF, QPointF, QRectF, QSize, QTimer, pyqtSignal, pyqtSignature
from PyQt4.QtGui import QAction, QBrush, QColor, QCommonStyle, QLinearGradient, QIcon, QMenu, QPainter, QPainterPath, QPalette, QPen, QPixmap from PyQt4.QtGui import QAction, QBrush, QColor, QCommonStyle, QLinearGradient, QIcon, QMenu, QPainter, QPainterPath, QPalette, QPen, QPixmap
from PyQt4.QtGui import QPolygonF, QPushButton, QStyle, QStyleOptionToolButton, QStylePainter, QToolButton from PyQt4.QtGui import QPolygonF, QPushButton, QStyle, QStyleOptionToolButton, QStylePainter, QToolButton
...@@ -10,8 +7,13 @@ from blink.resources import Resources ...@@ -10,8 +7,13 @@ from blink.resources import Resources
from blink.widgets.color import ColorScheme, ColorUtils, ColorHelperMixin from blink.widgets.color import ColorScheme, ColorUtils, ColorHelperMixin
__all__ = ['ToolButton', 'ConferenceButton', 'StreamButton', 'SegmentButton', 'SingleSegment', 'LeftSegment', 'MiddleSegment', 'RightSegment',
'RecordButton', 'SwitchViewButton', 'StateButton', 'AccountState']
class ToolButton(QToolButton): class ToolButton(QToolButton):
"""A custom QToolButton that doesn't show a menu indicator arrow""" """A custom QToolButton that doesn't show a menu indicator arrow"""
def paintEvent(self, event): def paintEvent(self, event):
painter = QStylePainter(self) painter = QStylePainter(self)
option = QStyleOptionToolButton() option = QStyleOptionToolButton()
...@@ -102,10 +104,12 @@ class SegmentTypeMeta(type): ...@@ -102,10 +104,12 @@ class SegmentTypeMeta(type):
def __repr__(cls): def __repr__(cls):
return cls.__name__ return cls.__name__
class SegmentType(object): class SegmentType(object):
__metaclass__ = SegmentTypeMeta __metaclass__ = SegmentTypeMeta
style_sheet = '' style_sheet = ''
class SingleSegment(SegmentType): class SingleSegment(SegmentType):
style_sheet = """ style_sheet = """
QToolButton { QToolButton {
...@@ -122,6 +126,7 @@ class SingleSegment(SegmentType): ...@@ -122,6 +126,7 @@ class SingleSegment(SegmentType):
} }
""" """
class LeftSegment(SegmentType): class LeftSegment(SegmentType):
style_sheet = """ style_sheet = """
QToolButton { QToolButton {
...@@ -139,6 +144,7 @@ class LeftSegment(SegmentType): ...@@ -139,6 +144,7 @@ class LeftSegment(SegmentType):
} }
""" """
class MiddleSegment(SegmentType): class MiddleSegment(SegmentType):
style_sheet = """ style_sheet = """
QToolButton { QToolButton {
...@@ -155,6 +161,7 @@ class MiddleSegment(SegmentType): ...@@ -155,6 +161,7 @@ class MiddleSegment(SegmentType):
} }
""" """
class RightSegment(SegmentType): class RightSegment(SegmentType):
style_sheet = """ style_sheet = """
QToolButton { QToolButton {
...@@ -285,7 +292,7 @@ class SwitchViewButton(QPushButton): ...@@ -285,7 +292,7 @@ class SwitchViewButton(QPushButton):
self.setAcceptDrops(True) self.setAcceptDrops(True)
self.__dict__['dnd_active'] = False self.__dict__['dnd_active'] = False
self.view = self.ContactView self.view = self.ContactView
self.original_height = 20 # used to restore button size after DND self.original_height = 20 # used to restore button size after DND
self.dnd_timer = QTimer(self) self.dnd_timer = QTimer(self)
self.dnd_timer.setInterval(100) self.dnd_timer.setInterval(100)
self.dnd_timer.timeout.connect(self._update_dnd) self.dnd_timer.timeout.connect(self._update_dnd)
...@@ -355,16 +362,16 @@ class SwitchViewButton(QPushButton): ...@@ -355,16 +362,16 @@ class SwitchViewButton(QPushButton):
def dragLeaveEvent(self, event): def dragLeaveEvent(self, event):
if self.dnd_active: if self.dnd_active:
self.dnd_timer.stop() self.dnd_timer.stop()
self.dnd_timer.phase = 0 self.dnd_timer.phase = 0
self.setStyleSheet(self.dnd_style_sheet1) self.setStyleSheet(self.dnd_style_sheet1)
super(SwitchViewButton, self).dragLeaveEvent(event) super(SwitchViewButton, self).dragLeaveEvent(event)
def dropEvent(self, event): def dropEvent(self, event):
if self.dnd_active: if self.dnd_active:
self.dnd_timer.stop() self.dnd_timer.stop()
self.dnd_timer.phase = 0 self.dnd_timer.phase = 0
self.setStyleSheet(self.dnd_style_sheet1) self.setStyleSheet(self.dnd_style_sheet1)
event.ignore() event.ignore()
...@@ -387,7 +394,7 @@ class StateButtonStyle(QCommonStyle, ColorHelperMixin): ...@@ -387,7 +394,7 @@ class StateButtonStyle(QCommonStyle, ColorHelperMixin):
return super(StateButtonStyle, self).sizeFromContents(element, option, size, widget) return super(StateButtonStyle, self).sizeFromContents(element, option, size, widget)
def toolButtonSizeFromContents(self, option, size, widget): def toolButtonSizeFromContents(self, option, size, widget):
# Make width >= height to avoid super-skiny buttons # Make width >= height to avoid super-skinny buttons
margin = 2 * (self._pixel_metrics[QStyle.PM_DefaultFrameWidth] + self._pixel_metrics[QStyle.PM_ButtonMargin]) margin = 2 * (self._pixel_metrics[QStyle.PM_DefaultFrameWidth] + self._pixel_metrics[QStyle.PM_ButtonMargin])
if option.features & QStyleOptionToolButton.MenuButtonPopup: if option.features & QStyleOptionToolButton.MenuButtonPopup:
margin_size = QSize(margin+1, margin) margin_size = QSize(margin+1, margin)
...@@ -448,12 +455,12 @@ class StateButtonStyle(QCommonStyle, ColorHelperMixin): ...@@ -448,12 +455,12 @@ class StateButtonStyle(QCommonStyle, ColorHelperMixin):
blend.setColorAt(0.9, self.color_with_alpha(focus_color, 0x45)) blend.setColorAt(0.9, self.color_with_alpha(focus_color, 0x45))
blend.setColorAt(1.0, self.color_with_alpha(ColorUtils.mix(focus_color, shadow_color, 0.4), 0x55)) blend.setColorAt(1.0, self.color_with_alpha(ColorUtils.mix(focus_color, shadow_color, 0.4), 0x55))
else: else:
blend.setColorAt(0.0, Qt.transparent) # or @0.5 blend.setColorAt(0.0, Qt.transparent) # or @0.5
blend.setColorAt(0.9, self.color_with_alpha(shadow_color, 0x10)) blend.setColorAt(0.9, self.color_with_alpha(shadow_color, 0x10))
#blend.setColorAt(1-4.0/glow_rect.height(), self.color_with_alpha(shadow_color, 0x10)) # this is for exactly 4 pixels from bottom # blend.setColorAt(1-4.0/glow_rect.height(), self.color_with_alpha(shadow_color, 0x10)) # this is for exactly 4 pixels from bottom
blend.setColorAt(1.0, self.color_with_alpha(shadow_color, 0x30)) # 0x25, 0x30 or 0x35 blend.setColorAt(1.0, self.color_with_alpha(shadow_color, 0x30)) # 0x25, 0x30 or 0x35
painter.setBrush(blend) painter.setBrush(blend)
painter.drawRoundedRect(glow_rect, 5, 5) # 5 or 6 painter.drawRoundedRect(glow_rect, 5, 5) # 5 or 6
# shadow # shadow
painter.setCompositionMode(QPainter.CompositionMode_SourceOver) painter.setCompositionMode(QPainter.CompositionMode_SourceOver)
...@@ -466,7 +473,7 @@ class StateButtonStyle(QCommonStyle, ColorHelperMixin): ...@@ -466,7 +473,7 @@ class StateButtonStyle(QCommonStyle, ColorHelperMixin):
blend.setColorAt(0.00, self.color_with_alpha(shadow_color, 0x10)) blend.setColorAt(0.00, self.color_with_alpha(shadow_color, 0x10))
blend.setColorAt(1.00, self.color_with_alpha(shadow_color, 0x80)) blend.setColorAt(1.00, self.color_with_alpha(shadow_color, 0x80))
painter.setBrush(blend) painter.setBrush(blend)
painter.drawRoundedRect(shadow_rect, 4, 4) # 4 or 5 painter.drawRoundedRect(shadow_rect, 4, 4) # 4 or 5
# border # border
painter.setCompositionMode(QPainter.CompositionMode_Source) painter.setCompositionMode(QPainter.CompositionMode_Source)
...@@ -510,12 +517,12 @@ class StateButtonStyle(QCommonStyle, ColorHelperMixin): ...@@ -510,12 +517,12 @@ class StateButtonStyle(QCommonStyle, ColorHelperMixin):
blend.setColorAt(0.0, self.color_with_alpha(shadow_color, 0x80)) blend.setColorAt(0.0, self.color_with_alpha(shadow_color, 0x80))
blend.setColorAt(1.0, self.color_with_alpha(shadow_color, 0x20)) blend.setColorAt(1.0, self.color_with_alpha(shadow_color, 0x20))
painter.setBrush(blend) painter.setBrush(blend)
painter.drawRoundedRect(hole_rect, 4, 4) # 4 or 5 painter.drawRoundedRect(hole_rect, 4, 4) # 4 or 5
# shadow # shadow
painter.setCompositionMode(QPainter.CompositionMode_Source) painter.setCompositionMode(QPainter.CompositionMode_Source)
painter.setBrush(content_grad) painter.setBrush(content_grad)
painter.drawRoundedRect(shadow_rect, 4, 4) # 5 or 6 painter.drawRoundedRect(shadow_rect, 4, 4) # 5 or 6
painter.setCompositionMode(QPainter.CompositionMode_SourceOver) painter.setCompositionMode(QPainter.CompositionMode_SourceOver)
blend = QLinearGradient(shadow_rect.topLeft(), shadow_rect.bottomLeft()) blend = QLinearGradient(shadow_rect.topLeft(), shadow_rect.bottomLeft())
blend.setColorAt(0.0, self.color_with_alpha(shadow_color, 0x40)) blend.setColorAt(0.0, self.color_with_alpha(shadow_color, 0x40))
...@@ -523,7 +530,7 @@ class StateButtonStyle(QCommonStyle, ColorHelperMixin): ...@@ -523,7 +530,7 @@ class StateButtonStyle(QCommonStyle, ColorHelperMixin):
blend.setColorAt(0.9, self.color_with_alpha(shadow_color, 0x07)) blend.setColorAt(0.9, self.color_with_alpha(shadow_color, 0x07))
blend.setColorAt(1.0, shade_color) blend.setColorAt(1.0, shade_color)
painter.setBrush(blend) painter.setBrush(blend)
painter.drawRoundedRect(shadow_rect, 4, 4) # 5 or 6 painter.drawRoundedRect(shadow_rect, 4, 4) # 5 or 6
# content # content
painter.setCompositionMode(QPainter.CompositionMode_Source) painter.setCompositionMode(QPainter.CompositionMode_Source)
...@@ -685,6 +692,7 @@ class AccountState(StateButton): ...@@ -685,6 +692,7 @@ class AccountState(StateButton):
def _get_history(self): def _get_history(self):
return [(action.state.name, action.note) for action in self.menu().actions()[5:]] return [(action.state.name, action.note) for action in self.menu().actions()[5:]]
def _set_history(self, values): def _set_history(self, values):
menu = self.menu() menu = self.menu()
for action in menu.actions()[5:]: for action in menu.actions()[5:]:
...@@ -698,6 +706,7 @@ class AccountState(StateButton): ...@@ -698,6 +706,7 @@ class AccountState(StateButton):
action.state = state action.state = state
action.note = note action.note = note
menu.addAction(action) menu.addAction(action)
history = property(_get_history, _set_history) history = property(_get_history, _set_history)
del _get_history, _set_history del _get_history, _set_history
......
__all__ = ['ColorScheme', 'ColorUtils', 'ColorHelperMixin']
from PyQt4.QtCore import Qt from PyQt4.QtCore import Qt
from PyQt4.QtGui import QColor from PyQt4.QtGui import QColor
from application.python import limit from application.python import limit
...@@ -8,8 +6,11 @@ from application.python.decorator import decorator, preserve_signature ...@@ -8,8 +6,11 @@ from application.python.decorator import decorator, preserve_signature
from math import fmod, isnan from math import fmod, isnan
__all__ = ['ColorScheme', 'ColorUtils', 'ColorHelperMixin']
class HCYColor(object): class HCYColor(object):
"""Hue/chroma/luma colorspace""" """Hue/chroma/luma color space"""
luma_r = 0.2126 luma_r = 0.2126
luma_g = 0.7152 luma_g = 0.7152
...@@ -202,9 +203,11 @@ class ColorUtils(object): ...@@ -202,9 +203,11 @@ class ColorUtils(object):
def color_key(instance, color): def color_key(instance, color):
return color.rgba() return color.rgba()
def color_ratio_key(instance, color, ratio): def color_ratio_key(instance, color, ratio):
return color.rgba() << 32 | int(ratio*512) return color.rgba() << 32 | int(ratio*512)
def background_color_key(instance, background, color): def background_color_key(instance, background, color):
return background.rgba() << 32 | color.rgba() return background.rgba() << 32 | color.rgba()
...@@ -276,7 +279,7 @@ class ColorHelperMixin(object): ...@@ -276,7 +279,7 @@ class ColorHelperMixin(object):
shadow_color = ColorUtils.mix(Qt.black, color, color.alphaF()) shadow_color = ColorUtils.mix(Qt.black, color, color.alphaF())
else: else:
shadow_color = ColorScheme.shade(ColorUtils.mix(Qt.black, color, color.alphaF()), ColorScheme.ShadowShade, self._contrast) shadow_color = ColorScheme.shade(ColorUtils.mix(Qt.black, color, color.alphaF()), ColorScheme.ShadowShade, self._contrast)
shadow_color.setAlpha(color.alpha()) # make sure shadow color has the same alpha channel as the input shadow_color.setAlpha(color.alpha()) # make sure shadow color has the same alpha channel as the input
return shadow_color return shadow_color
@cache_result(color_ratio_key) @cache_result(color_ratio_key)
......
__all__ = ['SlidingStackedWidget']
from PyQt4.QtCore import QEasingCurve, QParallelAnimationGroup, QPropertyAnimation, QPoint, pyqtSignal from PyQt4.QtCore import QEasingCurve, QParallelAnimationGroup, QPropertyAnimation, QPoint, pyqtSignal
from PyQt4.QtGui import QStackedWidget from PyQt4.QtGui import QStackedWidget
from blink.widgets.util import QtDynamicProperty from blink.widgets.util import QtDynamicProperty
__all__ = ['SlidingStackedWidget']
class SlidingStackedWidget(QStackedWidget): class SlidingStackedWidget(QStackedWidget):
animationEasingCurve = QtDynamicProperty('animationEasingCurve', int) animationEasingCurve = QtDynamicProperty('animationEasingCurve', int)
animationDuration = QtDynamicProperty('animationDuration', int) animationDuration = QtDynamicProperty('animationDuration', int)
...@@ -65,9 +66,9 @@ class SlidingStackedWidget(QStackedWidget): ...@@ -65,9 +66,9 @@ class SlidingStackedWidget(QStackedWidget):
next_widget.setGeometry(0, 0, width, height) next_widget.setGeometry(0, 0, width, height)
if direction in (self.TopToBottom, self.BottomToTop): if direction in (self.TopToBottom, self.BottomToTop):
offset = QPoint(0, height if direction==self.TopToBottom else -height) offset = QPoint(0, height if direction == self.TopToBottom else -height)
elif direction in (self.LeftToRight, self.RightToLeft): elif direction in (self.LeftToRight, self.RightToLeft):
offset = QPoint(width if direction==self.LeftToRight else -width, 0) offset = QPoint(width if direction == self.LeftToRight else -width, 0)
# re-position the next widget outside of the display area # re-position the next widget outside of the display area
prev_widget_position = prev_widget.pos() prev_widget_position = prev_widget.pos()
...@@ -100,8 +101,8 @@ class SlidingStackedWidget(QStackedWidget): ...@@ -100,8 +101,8 @@ class SlidingStackedWidget(QStackedWidget):
prev_widget = prev_widget_animation.targetObject() prev_widget = prev_widget_animation.targetObject()
next_widget = next_widget_animation.targetObject() next_widget = next_widget_animation.targetObject()
self.setCurrentWidget(next_widget) self.setCurrentWidget(next_widget)
prev_widget.hide() # this may have been done already by QStackedWidget when changing the current widget above -Dan prev_widget.hide() # this may have been done already by QStackedWidget when changing the current widget above -Dan
prev_widget.move(prev_widget_animation.startValue()) # move the outshifted widget back to its original position prev_widget.move(prev_widget_animation.startValue()) # move the out-shifted widget back to its original position
self._animation_group.clear() self._animation_group.clear()
self._active = False self._active = False
self.animationFinished.emit() self.animationFinished.emit()
......
__all__ = ['BackgroundFrame']
from PyQt4.QtCore import Qt, QEvent, QPoint, QRect, QSize from PyQt4.QtCore import Qt, QEvent, QPoint, QRect, QSize
from PyQt4.QtGui import QColor, QFrame, QPainter, QPixmap from PyQt4.QtGui import QColor, QFrame, QPainter, QPixmap
...@@ -8,6 +6,9 @@ from blink.resources import Resources ...@@ -8,6 +6,9 @@ from blink.resources import Resources
from blink.widgets.util import QtDynamicProperty from blink.widgets.util import QtDynamicProperty
__all__ = ['BackgroundFrame']
class BackgroundFrame(QFrame): class BackgroundFrame(QFrame):
backgroundColor = QtDynamicProperty('backgroundColor', unicode) backgroundColor = QtDynamicProperty('backgroundColor', unicode)
backgroundImage = QtDynamicProperty('backgroundImage', unicode) backgroundImage = QtDynamicProperty('backgroundImage', unicode)
...@@ -28,7 +29,7 @@ class BackgroundFrame(QFrame): ...@@ -28,7 +29,7 @@ class BackgroundFrame(QFrame):
@property @property
def image_size(self): def image_size(self):
if self.imageGeometry is not None: if self.imageGeometry is not None:
size = self.imageGeometry.size().expandedTo(QSize(0, 0)) # requested size with negative values turned to 0 size = self.imageGeometry.size().expandedTo(QSize(0, 0)) # requested size with negative values turned to 0
if size.isNull(): if size.isNull():
return size if self.pixmap is None else self.pixmap.size() return size if self.pixmap is None else self.pixmap.size()
elif size.width() == 0: elif size.width() == 0:
...@@ -70,4 +71,3 @@ class BackgroundFrame(QFrame): ...@@ -70,4 +71,3 @@ class BackgroundFrame(QFrame):
painter.drawPixmap(self.image_position, self.scaled_pixmap) painter.drawPixmap(self.image_position, self.scaled_pixmap)
painter.end() painter.end()
__all__ = ['Graph', 'GraphWidget', 'HeightScaler', 'LogarithmicScaler', 'MaxScaler', 'SoftScaler']
from PyQt4.QtCore import Qt, QLine, QPointF, QMetaObject, pyqtSignal from PyQt4.QtCore import Qt, QLine, QPointF, QMetaObject, pyqtSignal
from PyQt4.QtGui import QColor, QLinearGradient, QPainterPath, QPen, QPolygonF, QStyle, QStyleOption, QStylePainter, QWidget from PyQt4.QtGui import QColor, QLinearGradient, QPainterPath, QPen, QPolygonF, QStyle, QStyleOption, QStylePainter, QWidget
...@@ -14,6 +12,9 @@ from blink.widgets.color import ColorHelperMixin ...@@ -14,6 +12,9 @@ from blink.widgets.color import ColorHelperMixin
from blink.widgets.util import QtDynamicProperty from blink.widgets.util import QtDynamicProperty
__all__ = ['Graph', 'GraphWidget', 'HeightScaler', 'LogarithmicScaler', 'MaxScaler', 'SoftScaler']
class HeightScaler(object): class HeightScaler(object):
__metaclass__ = ABCMeta __metaclass__ = ABCMeta
...@@ -140,7 +141,7 @@ class GraphWidget(QWidget, ColorHelperMixin): ...@@ -140,7 +141,7 @@ class GraphWidget(QWidget, ColorHelperMixin):
option = QStyleOption() option = QStyleOption()
option.initFrom(self) option.initFrom(self)
contents_rect = self.style().subElementRect(QStyle.SE_FrameContents, option, self) or self.contentsRect() # the SE_FrameContents rect is Null unless the stylesheet defines decorations contents_rect = self.style().subElementRect(QStyle.SE_FrameContents, option, self) or self.contentsRect() # the SE_FrameContents rect is Null unless the stylesheet defines decorations
if self.graphStyle == self.BarStyle: if self.graphStyle == self.BarStyle:
graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width()) / self.horizontalPixelsPerUnit)) graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width()) / self.horizontalPixelsPerUnit))
...@@ -196,18 +197,18 @@ class GraphWidget(QWidget, ColorHelperMixin): ...@@ -196,18 +197,18 @@ class GraphWidget(QWidget, ColorHelperMixin):
cx_offset = self.horizontalPixelsPerUnit / 3.0 cx_offset = self.horizontalPixelsPerUnit / 3.0
smoothness = self.smoothFactor smoothness = self.smoothFactor
last_values = deque(3*[dataset.next() * height_scaling], maxlen=3) # last 3 values: 0 last, 1 previous, 2 previous previous last_values = deque(3*[next(dataset) * height_scaling], maxlen=3) # last 3 values: 0 last, 1 previous, 2 previous previous
envelope = QPainterPath() envelope = QPainterPath()
envelope.moveTo(0, last_values[0]) envelope.moveTo(0, last_values[0])
for x, y in enumerate(dataset, 1): for x, y in enumerate(dataset, 1):
x = x * self.horizontalPixelsPerUnit x *= self.horizontalPixelsPerUnit
y = y * height_scaling * (1 - smoothness) + last_values[0] * smoothness y *= height_scaling * (1 - smoothness) + last_values[0] * smoothness
last_values.appendleft(y) last_values.appendleft(y)
c1x = x - cx_offset * 2 c1x = x - cx_offset * 2
c2x = x - cx_offset c2x = x - cx_offset
c1y = limit((1 + smoothness) * last_values[1] - smoothness * last_values[2], min_value, max_value) # same gradient as previous previous value to previous value c1y = limit((1 + smoothness) * last_values[1] - smoothness * last_values[2], min_value, max_value) # same gradient as previous previous value to previous value
c2y = limit((1 - smoothness) * last_values[0] + smoothness * last_values[1], min_value, max_value) # same gradient as previous value to last value c2y = limit((1 - smoothness) * last_values[0] + smoothness * last_values[1], min_value, max_value) # same gradient as previous value to last value
envelope.cubicTo(c1x, c1y, c2x, c2y, x, y) envelope.cubicTo(c1x, c1y, c2x, c2y, x, y)
else: else:
envelope = QPainterPath() envelope = QPainterPath()
...@@ -236,7 +237,7 @@ class GraphWidget(QWidget, ColorHelperMixin): ...@@ -236,7 +237,7 @@ class GraphWidget(QWidget, ColorHelperMixin):
painter.restore() painter.restore()
# queue the 'updated' signal to be emited after returning to the main loop # queue the 'updated' signal to be emitted after returning to the main loop
QMetaObject.invokeMethod(self, 'updated', Qt.QueuedConnection) QMetaObject.invokeMethod(self, 'updated', Qt.QueuedConnection)
def add_graph(self, graph): def add_graph(self, graph):
...@@ -254,4 +255,3 @@ class GraphWidget(QWidget, ColorHelperMixin): ...@@ -254,4 +255,3 @@ class GraphWidget(QWidget, ColorHelperMixin):
self.graphs = [] self.graphs = []
self.update() self.update()
__all__ = ['DurationLabel', 'IconSelector', 'LatencyLabel', 'PacketLossLabel', 'Status', 'StatusLabel', 'StreamInfoLabel', 'ElidedLabel', 'ContactState']
import os import os
from datetime import timedelta from datetime import timedelta
...@@ -16,6 +14,9 @@ from blink.widgets.color import ColorHelperMixin ...@@ -16,6 +14,9 @@ from blink.widgets.color import ColorHelperMixin
from blink.widgets.util import QtDynamicProperty, ContextMenuActions from blink.widgets.util import QtDynamicProperty, ContextMenuActions
__all__ = ['DurationLabel', 'IconSelector', 'LatencyLabel', 'PacketLossLabel', 'Status', 'StatusLabel', 'StreamInfoLabel', 'ElidedLabel', 'ContactState']
class IconSelector(QLabel): class IconSelector(QLabel):
default_icon = QtDynamicProperty('default_icon', QIcon) default_icon = QtDynamicProperty('default_icon', QIcon)
icon_size = QtDynamicProperty('icon_size', int) icon_size = QtDynamicProperty('icon_size', int)
...@@ -283,6 +284,7 @@ class StateColor(QColor): ...@@ -283,6 +284,7 @@ class StateColor(QColor):
def stroke(self): def stroke(self):
return self.darker(200) return self.darker(200)
class StateColorMapping(dict): class StateColorMapping(dict):
def __missing__(self, key): def __missing__(self, key):
if key == 'offline': if key == 'offline':
...@@ -294,7 +296,7 @@ class StateColorMapping(dict): ...@@ -294,7 +296,7 @@ class StateColorMapping(dict):
elif key == 'busy': elif key == 'busy':
return self.setdefault(key, StateColor('#ff0000')) return self.setdefault(key, StateColor('#ff0000'))
else: else:
return StateColor(Qt.transparent) #StateColor('#d0d0d0') return StateColor(Qt.transparent) # StateColor('#d0d0d0')
class ContactState(QLabel, ColorHelperMixin): class ContactState(QLabel, ColorHelperMixin):
...@@ -323,4 +325,3 @@ class ContactState(QLabel, ColorHelperMixin): ...@@ -323,4 +325,3 @@ class ContactState(QLabel, ColorHelperMixin):
painter.setPen(QPen(QBrush(gradient), 1)) painter.setPen(QPen(QBrush(gradient), 1))
painter.drawRoundedRect(-4, 0, self.width()+4, self.height(), 3.7, 3.7) painter.drawRoundedRect(-4, 0, self.width()+4, self.height(), 3.7, 3.7)
__all__ = ['LineEdit', 'ValidatingLineEdit', 'SearchBox', 'LocationBar']
import re import re
from PyQt4.QtCore import Qt, QEvent, pyqtSignal from PyQt4.QtCore import Qt, QEvent, pyqtSignal
...@@ -10,6 +8,9 @@ from blink.resources import Resources ...@@ -10,6 +8,9 @@ from blink.resources import Resources
from blink.widgets.util import QtDynamicProperty from blink.widgets.util import QtDynamicProperty
__all__ = ['LineEdit', 'ValidatingLineEdit', 'SearchBox', 'LocationBar']
class SideWidget(QWidget): class SideWidget(QWidget):
sizeHintChanged = pyqtSignal() sizeHintChanged = pyqtSignal()
...@@ -64,7 +65,7 @@ class LineEdit(QLineEdit): ...@@ -64,7 +65,7 @@ class LineEdit(QLineEdit):
spacing = self.right_layout.spacing() spacing = self.right_layout.spacing()
text_rect = self.style().subElementRect(QStyle.SE_LineEditContents, option, self) text_rect = self.style().subElementRect(QStyle.SE_LineEditContents, option, self)
text_rect.adjust(spacing, 0, -spacing, 0) text_rect.adjust(spacing, 0, -spacing, 0)
mid_height = text_rect.center().y() + 1 - (text_rect.height() % 2) # need -1 correction for odd heights -Dan mid_height = text_rect.center().y() + 1 - (text_rect.height() % 2) # need -1 correction for odd heights -Dan
if self.left_layout.count() > 0: if self.left_layout.count() > 0:
left_height = mid_height - self.left_widget.height()/2 left_height = mid_height - self.left_widget.height()/2
left_width = self.left_widget.width() left_width = self.left_widget.width()
...@@ -244,7 +245,7 @@ class ClearButton(QAbstractButton): ...@@ -244,7 +245,7 @@ class ClearButton(QAbstractButton):
# Mid is darker than Dark. Go figure... -Dan # Mid is darker than Dark. Go figure... -Dan
bg_color = palette.color(QPalette.Mid) if self.isDown() else palette.color(QPalette.Dark) bg_color = palette.color(QPalette.Mid) if self.isDown() else palette.color(QPalette.Dark)
fg_color = palette.color(QPalette.Window) # or QPalette.Base for white fg_color = palette.color(QPalette.Window) # or QPalette.Base for white
painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.Antialiasing, True)
painter.setBrush(bg_color) painter.setBrush(bg_color)
...@@ -307,4 +308,3 @@ class LocationBar(LineEdit): ...@@ -307,4 +308,3 @@ class LocationBar(LineEdit):
def _SH_TextChanged(self, text): def _SH_TextChanged(self, text):
self.clear_button.setVisible(bool(text)) self.clear_button.setVisible(bool(text))
__all__ = ['QtDynamicProperty', 'ContextMenuActions']
from PyQt4.QtCore import QPyNullVariant from PyQt4.QtCore import QPyNullVariant
__all__ = ['QtDynamicProperty', 'ContextMenuActions']
class QtDynamicProperty(object): class QtDynamicProperty(object):
def __init__(self, name, type=unicode): def __init__(self, name, type=unicode):
self.name = name self.name = name
self.type = type self.type = type
def __get__(self, obj, objtype):
if obj is None: def __get__(self, instance, owner):
if instance is None:
return self return self
value = obj.property(self.name) value = instance.property(self.name)
if isinstance(value, QPyNullVariant): if isinstance(value, QPyNullVariant):
value = self.type() value = self.type()
return value return value
def __set__(self, obj, value): def __set__(self, obj, value):
if value is not None and not isinstance(value, self.type): if value is not None and not isinstance(value, self.type):
value = self.type(value) value = self.type(value)
obj.setProperty(self.name, value) obj.setProperty(self.name, value)
def __delete__(self, obj): def __delete__(self, obj):
raise AttributeError("attribute cannot be deleted") raise AttributeError("attribute cannot be deleted")
......
from __future__ import division from __future__ import division
__all__ = ['VideoSurface']
from PyQt4.QtCore import Qt, QMetaObject, QPoint, QRect, QTimer, pyqtSignal from PyQt4.QtCore import Qt, QMetaObject, QPoint, QRect, QTimer, pyqtSignal
from PyQt4.QtGui import QColor, QCursor, QIcon, QImage, QPainter, QPixmap, QTransform, QWidget from PyQt4.QtGui import QColor, QCursor, QIcon, QImage, QPainter, QPixmap, QTransform, QWidget
...@@ -16,7 +12,11 @@ from sipsimple.core import FrameBufferVideoRenderer ...@@ -16,7 +12,11 @@ from sipsimple.core import FrameBufferVideoRenderer
from blink.resources import Resources from blink.resources import Resources
class Container(object): pass __all__ = ['VideoSurface']
class Container(object):
pass
class InteractionState(object): class InteractionState(object):
...@@ -41,7 +41,7 @@ class VideoSurface(QWidget): ...@@ -41,7 +41,7 @@ class VideoSurface(QWidget):
class BottomLeftCorner: __metaclass__ = MarkerType class BottomLeftCorner: __metaclass__ = MarkerType
class BottomRightCorner: __metaclass__ = MarkerType class BottomRightCorner: __metaclass__ = MarkerType
adjusted = pyqtSignal(QRect, QRect) # the widget was adjusted by the user (if interactive) adjusted = pyqtSignal(QRect, QRect) # the widget was adjusted by the user (if interactive)
interactive = False # if the widget can be interacted with (moved, resized) interactive = False # if the widget can be interacted with (moved, resized)
mirror = False # mirror the image horizontally mirror = False # mirror the image horizontally
...@@ -197,13 +197,13 @@ class VideoSurface(QWidget): ...@@ -197,13 +197,13 @@ class VideoSurface(QWidget):
delta_x = -(self.width_for_height(geometry.height() - delta_y) - geometry.width()) delta_x = -(self.width_for_height(geometry.height() - delta_y) - geometry.width())
geometry.setTopLeft(geometry.topLeft() + QPoint(delta_x, delta_y)) geometry.setTopLeft(geometry.topLeft() + QPoint(delta_x, delta_y))
elif self._interaction.resize_corner is self.TopRightCorner: elif self._interaction.resize_corner is self.TopRightCorner:
delta_x = (self.width_for_height(geometry.height() - delta_y) - geometry.width()) delta_x = +(self.width_for_height(geometry.height() - delta_y) - geometry.width())
geometry.setTopRight(geometry.topRight() + QPoint(delta_x, delta_y)) geometry.setTopRight(geometry.topRight() + QPoint(delta_x, delta_y))
elif self._interaction.resize_corner is self.BottomLeftCorner: elif self._interaction.resize_corner is self.BottomLeftCorner:
delta_x = -(self.width_for_height(geometry.height() + delta_y) - geometry.width()) delta_x = -(self.width_for_height(geometry.height() + delta_y) - geometry.width())
geometry.setBottomLeft(geometry.bottomLeft() + QPoint(delta_x, delta_y)) geometry.setBottomLeft(geometry.bottomLeft() + QPoint(delta_x, delta_y))
else: else:
delta_x = (self.width_for_height(geometry.height() + delta_y) - geometry.width()) delta_x = +(self.width_for_height(geometry.height() + delta_y) - geometry.width())
geometry.setBottomRight(geometry.bottomRight() + QPoint(delta_x, delta_y)) geometry.setBottomRight(geometry.bottomRight() + QPoint(delta_x, delta_y))
if self.minimumHeight() <= geometry.height() <= self.maximumHeight() and (self.parent() is None or self.parent().rect().contains(geometry)): if self.minimumHeight() <= geometry.height() <= self.maximumHeight() and (self.parent() is None or self.parent().rect().contains(geometry)):
...@@ -224,4 +224,3 @@ class VideoSurface(QWidget): ...@@ -224,4 +224,3 @@ class VideoSurface(QWidget):
super(VideoSurface, self).closeEvent(event) super(VideoSurface, self).closeEvent(event)
self.stop() self.stop()
__all__ = ['ZRTPWidget']
from PyQt4 import uic from PyQt4 import uic
from PyQt4.QtCore import Qt, pyqtSignal from PyQt4.QtCore import Qt, pyqtSignal
from PyQt4.QtGui import QStyle, QStyleOption, QStylePainter from PyQt4.QtGui import QStyle, QStyleOption, QStylePainter
...@@ -9,8 +6,12 @@ from PyQt4.QtGui import QStyle, QStyleOption, QStylePainter ...@@ -9,8 +6,12 @@ from PyQt4.QtGui import QStyle, QStyleOption, QStylePainter
from blink.resources import Resources from blink.resources import Resources
__all__ = ['ZRTPWidget']
ui_class, base_class = uic.loadUiType(Resources.get('zrtp_widget.ui')) ui_class, base_class = uic.loadUiType(Resources.get('zrtp_widget.ui'))
class ZRTPWidget(base_class, ui_class): class ZRTPWidget(base_class, ui_class):
closed = pyqtSignal() closed = pyqtSignal()
nameChanged = pyqtSignal() nameChanged = pyqtSignal()
......
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