Exemplo n.º 1
0
class AccountInfo(object):
    active_icon = IconDescriptor(Resources.get('icons/circle-dot.svg'))
    inactive_icon = IconDescriptor(Resources.get('icons/circle-grey.svg'))
    activity_icon = IconDescriptor(Resources.get('icons/circle-progress.svg'))

    def __init__(self, account):
        self.account = account
        self.registration_state = None

    @property
    def name(self):
        return u'Bonjour' if self.account is BonjourAccount() else unicode(
            self.account.id)

    @property
    def icon(self):
        if self.registration_state == 'started':
            return self.activity_icon
        elif self.registration_state == 'succeeded':
            return self.active_icon
        else:
            return self.inactive_icon

    def __eq__(self, other):
        if isinstance(other, basestring):
            return self.name == other
        elif isinstance(other, (Account, BonjourAccount)):
            return self.account == other
        elif isinstance(other, AccountInfo):
            return self.account == other.account
        return False

    def __ne__(self, other):
        return not self.__eq__(other)
Exemplo n.º 2
0
class TLSSettingsExtension(TLSSettings):
    ca_list = Setting(type=ApplicationDataPath,
                      default=ApplicationDataPath(Resources.get('tls/ca.crt')),
                      nillable=True)
    certificate = Setting(type=ApplicationDataPath,
                          default=ApplicationDataPath(
                              Resources.get('tls/default.crt')),
                          nillable=True)
    verify_server = Setting(type=bool, default=True)
Exemplo n.º 3
0
class SoundSettings(SettingsGroup):
    inbound_ringtone = Setting(
        type=SoundFile,
        default=SoundFile(Resources.get('sounds/inbound_ringtone.wav')),
        nillable=True)
    outbound_ringtone = Setting(
        type=SoundFile,
        default=SoundFile(Resources.get('sounds/outbound_ringtone.wav')),
        nillable=True)
    play_message_alerts = Setting(type=bool, default=True)
Exemplo n.º 4
0
 def __init__(self, parent=None, framerate=None):
     super(VideoSurface, self).__init__(parent)
     self.setAttribute(Qt.WA_OpaquePaintEvent, True)
     self.setMouseTracking(True)
     self.cursors = Cursors()
     self.cursors.resize_top    = QCursor(QIcon(Resources.get('icons/resize-top.svg')).pixmap(16),    hotX=8,  hotY=0)
     self.cursors.resize_bottom = QCursor(QIcon(Resources.get('icons/resize-bottom.svg')).pixmap(16), hotX=8,  hotY=16)
     if framerate is not None:
         self._clock = QTimer()
         self._clock.setInterval(1000/framerate)
         self._clock.timeout.connect(self.update)
     else:
         self._clock = None
     self._interaction = InteractionState()
     self._image = None
Exemplo n.º 5
0
 def __init__(self, parent=None, framerate=None):
     super(VideoSurface, self).__init__(parent)
     self.setAttribute(Qt.WA_OpaquePaintEvent, True)
     self.setMouseTracking(True)
     self.cursors = Container()
     self.cursors.resize_top    = QCursor(QIcon(Resources.get('icons/resize-top.svg')).pixmap(16),    hotX=8,  hotY=0)
     self.cursors.resize_bottom = QCursor(QIcon(Resources.get('icons/resize-bottom.svg')).pixmap(16), hotX=8,  hotY=16)
     if framerate is not None:
         self._clock = QTimer()
         self._clock.setInterval(1000/framerate)
         self._clock.timeout.connect(self.update)
     else:
         self._clock = None
     self._interaction = InteractionState()
     self._image = None
Exemplo n.º 6
0
    def createRequest(self, op, req, data):
        #print "createRequest: req.url()", req.url()

        if req.url().host() != "webodf":
            return super(WebODFNetworkManager,
                         self).createRequest(op, req, data)

        path = QUrl("http://webodf/").resolved(req.url()).path()

        print "Request for", path

        if op == QNetworkAccessManager.GetOperation:
            reply = None
            if path.startswith("/dijit"):
                path = "/wodo" + path  # TODO: why gets wodo/ lost?
            resourcePath = Resources.get("documentsharing" + path)
            if os.path.exists(resourcePath):
                print "reply for resource:", resourcePath
                reply = ResourceReply(resourcePath, self)
            elif path == self.genesisDocumentPath:
                print "reply for genesis document:", self.genesisDocumentPath
                reply = ResourceReply(self.genesisDocumentPath, self)
            else:
                avatarUrl = self.sessionBackend.resolveAvatarUrl(path)
                if avatarUrl != "":
                    print "reply for avatar url:", avatarUrl
                    reply = ResourceReply(avatarUrl, self)

            if reply is not None:
                return reply

            print "Request for unknown resource:", path

        return super(WebODFNetworkManager, self).createRequest(op, req, data)
Exemplo n.º 7
0
 def __init__(self, model, parent=None):
     super(ServerToolsWindow, self).__init__(parent)
     with Resources.directory:
         self.setupUi(self)
     self.spinner_movie = QMovie(Resources.get("icons/servertools-spinner.mng"))
     self.spinner_label.setMovie(self.spinner_movie)
     self.spinner_label.hide()
     self.progress_bar.hide()
     while self.tab_widget.count():
         self.tab_widget.removeTab(0)  # remove the tab(s) added in designer
     self.tab_widget.tabBar().hide()
     self.account_button.setMenu(QMenu(self.account_button))
     self.setWindowTitle("Blink Server Tools")
     self.setWindowIconText("Server Tools")
     self.model = model
     self.tab_widget.addTab(ServerToolsWebView(self), "")
     font = self.account_label.font()
     font.setPointSizeF(self.account_label.fontInfo().pointSizeF() + 2)
     font.setFamily("Sans Serif")
     self.account_label.setFont(font)
     self.model.rowsInserted.connect(self._SH_ModelChanged)
     self.model.rowsRemoved.connect(self._SH_ModelChanged)
     self.account_button.menu().triggered.connect(self._SH_AccountButtonMenuTriggered)
     web_view = self.tab_widget.currentWidget()
     web_view.loadStarted.connect(self._SH_WebViewLoadStarted)
     web_view.loadFinished.connect(self._SH_WebViewLoadFinished)
     web_view.loadProgress.connect(self._SH_WebViewLoadProgress)
Exemplo n.º 8
0
 def _SH_WebViewLoadFinished(self, load_ok):
     self.spinner_movie.stop()
     self.spinner_label.hide()
     self.progress_bar.hide()
     if not load_ok:
         web_view = self.tab_widget.currentWidget()
         icon_path = Resources.get("icons/invalid.png")
         error_message = web_view.last_error or "Unknown error"
         html = """
         <html>
          <head>
           <style>
             .icon    { width: 64px; height: 64px; float: left; }
             .message { margin-left: 74px; line-height: 64px; vertical-align: middle; }
           </style>
          </head>
          <body>
           <img class="icon" src="file:%s" />
           <div class="message">Failed to load web page: <b>%s</b></div>
          </body>
         </html>
         """ % (
             icon_path,
             error_message,
         )
         web_view.loadStarted.disconnect(self._SH_WebViewLoadStarted)
         web_view.loadFinished.disconnect(self._SH_WebViewLoadFinished)
         web_view.setHtml(html)
         web_view.loadStarted.connect(self._SH_WebViewLoadStarted)
         web_view.loadFinished.connect(self._SH_WebViewLoadFinished)
Exemplo n.º 9
0
 def _SH_WebViewLoadFinished(self, load_ok):
     self.spinner_movie.stop()
     self.spinner_label.hide()
     self.progress_bar.hide()
     if not load_ok:
         web_view = self.tab_widget.currentWidget()
         icon_path = Resources.get('icons/invalid.png')
         error_message = web_view.last_error or 'Unknown error'
         html = """
         <html>
          <head>
           <style>
             .icon    { width: 64px; height: 64px; float: left; }
             .message { margin-left: 74px; line-height: 64px; vertical-align: middle; }
           </style>
          </head>
          <body>
           <img class="icon" src="file:%s" />
           <div class="message">Failed to load web page: <b>%s</b></div>
          </body>
         </html>
         """ % (icon_path, error_message)
         web_view.loadStarted.disconnect(self._SH_WebViewLoadStarted)
         web_view.loadFinished.disconnect(self._SH_WebViewLoadFinished)
         web_view.setHtml(html)
         web_view.loadStarted.connect(self._SH_WebViewLoadStarted)
         web_view.loadFinished.connect(self._SH_WebViewLoadFinished)
Exemplo n.º 10
0
    def createRequest(self, op, req, data):
        #print "createRequest: req.url()", req.url()

        if req.url().host() != "webodf":
            return super(WebODFNetworkManager, self).createRequest(op, req, data);

        path = QUrl("http://webodf/").resolved(req.url()).path()

        print "Request for", path

        if op == QNetworkAccessManager.GetOperation:
            reply = None;
            if path.startswith("/dijit"):
                path = "/wodo" + path # TODO: why gets wodo/ lost?
            resourcePath = Resources.get("documentsharing"+path)
            if os.path.exists(resourcePath):
                print "reply for resource:", resourcePath
                reply = ResourceReply(resourcePath, self)
            elif path == self.genesisDocumentPath:
                print "reply for genesis document:", self.genesisDocumentPath
                reply = ResourceReply(self.genesisDocumentPath, self)
            else:
                avatarUrl = self.sessionBackend.resolveAvatarUrl(path)
                if avatarUrl != "":
                    print "reply for avatar url:", avatarUrl
                    reply = ResourceReply(avatarUrl, self)

            if reply is not None:
                return  reply

            print "Request for unknown resource:", path

        return super(WebODFNetworkManager, self).createRequest(op, req, data)
Exemplo n.º 11
0
 def __init__(self, model, parent=None):
     super(ServerToolsWindow, self).__init__(parent)
     with Resources.directory:
         self.setupUi(self)
     self.spinner_movie = QMovie(
         Resources.get('icons/servertools-spinner.mng'))
     self.spinner_label.setMovie(self.spinner_movie)
     self.spinner_label.hide()
     self.progress_bar.hide()
     while self.tab_widget.count():
         self.tab_widget.removeTab(0)  # remove the tab(s) added in designer
     self.tab_widget.tabBar().hide()
     self.account_button.setMenu(QMenu(self.account_button))
     self.setWindowTitle('Blink Server Tools')
     self.setWindowIconText('Server Tools')
     self.model = model
     self.tab_widget.addTab(ServerToolsWebView(self), '')
     font = self.account_label.font()
     font.setPointSizeF(self.account_label.fontInfo().pointSizeF() + 2)
     font.setFamily("Sans Serif")
     self.account_label.setFont(font)
     self.model.rowsInserted.connect(self._SH_ModelChanged)
     self.model.rowsRemoved.connect(self._SH_ModelChanged)
     self.account_button.menu().triggered.connect(
         self._SH_AccountButtonMenuTriggered)
     web_view = self.tab_widget.currentWidget()
     web_view.loadStarted.connect(self._SH_WebViewLoadStarted)
     web_view.loadFinished.connect(self._SH_WebViewLoadFinished)
     web_view.loadProgress.connect(self._SH_WebViewLoadProgress)
Exemplo n.º 12
0
 def _set_filename(self, filename):
     self.__dict__['filename'] = filename
     filename = ApplicationData.get(filename) if filename else Resources.get(self.default_icon)
     pixmap = QPixmap()
     if pixmap.load(filename):
         self.setPixmap(pixmap.scaled(32, 32, Qt.KeepAspectRatio, Qt.SmoothTransformation))
     else:
         self.setPixmap(pixmap)
Exemplo n.º 13
0
class AnsweringMachineSettings(SettingsGroup):
    enabled = Setting(type=bool, default=False)
    answer_delay = Setting(type=NonNegativeInteger, default=10)
    max_recording = Setting(type=PositiveInteger, default=3)
    unavailable_message = Setting(
        type=SoundFile,
        default=SoundFile(Resources.get('sounds/unavailable_message.wav')),
        nillable=True)
Exemplo n.º 14
0
 def capture(self):
     try:
         self.image = self.vncclient.image.copy()
     except AttributeError:
         pass
     else:
         player = WavePlayer(SIPApplication.alert_audio_bridge.mixer, Resources.get('sounds/screenshot.wav'), volume=30)
         SIPApplication.alert_audio_bridge.add(player)
         player.start()
Exemplo n.º 15
0
 def setupUi(self):
     super(ServerToolsWindow, self).setupUi(self)
     self.account_button.default_avatar = QIcon(Resources.get('icons/default-avatar.png'))
     self.account_button.setIcon(IconManager().get('avatar') or self.account_button.default_avatar)
     self.account_button.setMenu(QMenu(self.account_button))
     self.back_button.setMenu(QMenu(self.back_button))
     self.back_button.setEnabled(False)
     self.forward_button.setMenu(QMenu(self.forward_button))
     self.forward_button.setEnabled(False)
Exemplo n.º 16
0
    def __init__(self):
        super(Blink, self).__init__(sys.argv)
        self.setAttribute(Qt.AA_DontShowIconsInMenus, False)
        self.sip_application = SIPApplication()
        self.first_run = False

        self.setOrganizationDomain("ag-projects.com")
        self.setOrganizationName("AG Projects")
        self.setApplicationName("Blink")
        self.setApplicationVersion(__version__)

        self.main_window = MainWindow()
        self.chat_window = ChatWindow()
        self.main_window.__closed__ = True
        self.chat_window.__closed__ = True
        self.main_window.installEventFilter(self)
        self.chat_window.installEventFilter(self)

        self.main_window.addAction(self.chat_window.control_button.actions.main_window)
        self.chat_window.addAction(self.main_window.quit_action)
        self.chat_window.addAction(self.main_window.help_action)
        self.chat_window.addAction(self.main_window.redial_action)
        self.chat_window.addAction(self.main_window.join_conference_action)
        self.chat_window.addAction(self.main_window.mute_action)
        self.chat_window.addAction(self.main_window.silent_action)
        self.chat_window.addAction(self.main_window.preferences_action)
        self.chat_window.addAction(self.main_window.transfers_window_action)
        self.chat_window.addAction(self.main_window.logs_window_action)
        self.chat_window.addAction(self.main_window.received_files_window_action)
        self.chat_window.addAction(self.main_window.screenshots_window_action)

        self.ip_address_monitor = IPAddressMonitor()
        self.log_manager = LogManager()
        self.presence_manager = PresenceManager()
        self.session_manager = SessionManager()
        self.update_manager = UpdateManager()

        # Prevent application from exiting after last window is closed if system tray was initialized
        if self.main_window.system_tray_icon:
            self.setQuitOnLastWindowClosed(False)

        self.main_window.check_for_updates_action.triggered.connect(self.update_manager.check_for_updates)
        self.main_window.check_for_updates_action.setVisible(self.update_manager != Null)

        if getattr(sys, "frozen", False):
            XMLDocument.schema_path = Resources.get("xml-schemas")

        Account.register_extension(AccountExtension)
        BonjourAccount.register_extension(BonjourAccountExtension)
        Contact.register_extension(ContactExtension)
        Group.register_extension(GroupExtension)
        SIPSimpleSettings.register_extension(SIPSimpleSettingsExtension)

        notification_center = NotificationCenter()
        notification_center.add_observer(self, sender=self.sip_application)

        branding.setup(self)
Exemplo n.º 17
0
    def __init__(self):
        super(Blink, self).__init__(sys.argv)
        self.setAttribute(Qt.AA_DontShowIconsInMenus, False)
        self.sip_application = SIPApplication()
        self.first_run = False

        self.setOrganizationDomain("ag-projects.com")
        self.setOrganizationName("AG Projects")
        self.setApplicationName("Blink")
        self.setApplicationVersion(__version__)

        self.main_window = MainWindow()
        self.chat_window = ChatWindow()
        self.main_window.__closed__ = True
        self.chat_window.__closed__ = True
        self.main_window.installEventFilter(self)
        self.chat_window.installEventFilter(self)

        self.main_window.addAction(self.chat_window.control_button.actions.main_window)
        self.chat_window.addAction(self.main_window.quit_action)
        self.chat_window.addAction(self.main_window.help_action)
        self.chat_window.addAction(self.main_window.redial_action)
        self.chat_window.addAction(self.main_window.join_conference_action)
        self.chat_window.addAction(self.main_window.mute_action)
        self.chat_window.addAction(self.main_window.silent_action)
        self.chat_window.addAction(self.main_window.preferences_action)
        self.chat_window.addAction(self.main_window.transfers_window_action)
        self.chat_window.addAction(self.main_window.logs_window_action)
        self.chat_window.addAction(self.main_window.received_files_window_action)
        self.chat_window.addAction(self.main_window.screenshots_window_action)

        self.ip_address_monitor = IPAddressMonitor()
        self.log_manager = LogManager()
        self.presence_manager = PresenceManager()
        self.session_manager = SessionManager()
        self.update_manager = UpdateManager()

        # Prevent application from exiting after last window is closed if system tray was initialized
        if self.main_window.system_tray_icon:
            self.setQuitOnLastWindowClosed(False)

        self.main_window.check_for_updates_action.triggered.connect(self.update_manager.check_for_updates)
        self.main_window.check_for_updates_action.setVisible(self.update_manager != Null)

        if getattr(sys, 'frozen', False):
            XMLDocument.schema_path = Resources.get('xml-schemas')

        Account.register_extension(AccountExtension)
        BonjourAccount.register_extension(BonjourAccountExtension)
        Contact.register_extension(ContactExtension)
        Group.register_extension(GroupExtension)
        SIPSimpleSettings.register_extension(SIPSimpleSettingsExtension)

        notification_center = NotificationCenter()
        notification_center.add_observer(self, sender=self.sip_application)

        branding.setup(self)
Exemplo n.º 18
0
 def setupUi(self):
     super(ServerToolsWindow, self).setupUi(self)
     self.account_button.default_avatar = QIcon(Resources.get('icons/default-avatar.png'))
     self.account_button.setIcon(IconManager().get('avatar') or self.account_button.default_avatar)
     self.account_button.setMenu(QMenu(self.account_button))
     self.back_button.setMenu(QMenu(self.back_button))
     self.back_button.setEnabled(False)
     self.forward_button.setMenu(QMenu(self.forward_button))
     self.forward_button.setEnabled(False)
Exemplo n.º 19
0
 def capture(self):
     try:
         self.image = self.vncclient.image.copy()
     except AttributeError:
         pass
     else:
         player = WavePlayer(SIPApplication.alert_audio_bridge.mixer, Resources.get('sounds/screenshot.wav'), volume=30)
         SIPApplication.alert_audio_bridge.add(player)
         player.start()
Exemplo n.º 20
0
 def __init__(self, parent=None, size=16):
     super(SearchIcon, self).__init__(parent)
     self.setFocusPolicy(Qt.NoFocus)
     self.setVisible(True)
     self.setMinimumSize(size+2, size+2)
     pixmap = QPixmap()
     if pixmap.load(Resources.get("icons/search.svg")):
         self.icon = pixmap.scaled(size, size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
     else:
         self.icon = None
Exemplo n.º 21
0
 def _NH_SIPAccountManagerDidAddAccount(self, notification):
     account = notification.data.account
     icon = None
     if account is BonjourAccount():
         pixmap = QPixmap()
         if pixmap.load(Resources.get("icons/bonjour.png")):
             pixmap = pixmap.scaled(16, 16, Qt.KeepAspectRatio, Qt.SmoothTransformation)
             icon = QIcon(pixmap)
     self.beginInsertRows(QModelIndex(), len(self.accounts), len(self.accounts))
     self.accounts.append(AccountInfo(account, icon))
     self.endInsertRows()
Exemplo n.º 22
0
 def __init__(self, parent=None, size=16):
     super(SearchIcon, self).__init__(parent)
     self.setFocusPolicy(Qt.NoFocus)
     self.setVisible(True)
     self.setMinimumSize(size + 2, size + 2)
     pixmap = QPixmap()
     if pixmap.load(Resources.get("icons/search.svg")):
         self.icon = pixmap.scaled(size, size, Qt.KeepAspectRatio,
                                   Qt.SmoothTransformation)
     else:
         self.icon = None
Exemplo n.º 23
0
class BlinkWebODFSessionBackendBase(QObject):

    default_user_icon_filename = Resources.get('icons/default-avatar.png')

    serverOpspecsArrived = pyqtSignal('QVariantMap')
    replayFinished = pyqtSignal()
    reconnectFinished = pyqtSignal()
    clientOpspecsSent = pyqtSignal('QVariantMap')
    closed = pyqtSignal()
    connectedChanged = pyqtSignal(bool)

    def __init__(self, account):
        super(BlinkWebODFSessionBackendBase, self).__init__();

        self.account = account
        self._hasUnsynchronizedChanges = False
        self._baseHeadId = ""

    # SessionBackend API
    @pyqtSlot(result="QString")
    def memberId(self):
        return str(self.account.uri)

    # SessionBackend API
    def resolveAvatarUrl(self, url):
        if url.startswith("/avatar/"):
            uri = SIPURI.parse(url[8:].decode("hex"))

            # TODO: see if there is an official way to get this, including notification of changes
            # also needs fixing of webodf, allowing custom avatar renderer
            if self.account.uri == uri:
                avatar = IconManager().get('avatar')
                return avatar.filename if avatar != None else self.default_user_icon_filename

            contact, contact_uri = URIUtils.find_contact(uri)
            return contact.icon.filename

        return ""

    # SessionBackend API
    @pyqtSlot()
    def close(self):
        self.closed.emit()

    # SessionBackend API
    @pyqtSlot('bool', 'QString')
    def updateSyncState(self, hasUnsynchronizedChanges, baseHeadId):
        print "updateSyncState: ", hasUnsynchronizedChanges, " baseHeadId: ", baseHeadId
        self._hasUnsynchronizedChanges = hasUnsynchronizedChanges
        self._baseHeadId = baseHeadId
Exemplo n.º 24
0
 def event(self, event):
     if event.type() == QEvent.DynamicPropertyChange:
         if event.propertyName() == 'backgroundImage':
             self.pixmap = QPixmap()
             if self.backgroundImage and self.pixmap.load(Resources.get(self.backgroundImage)):
                 self.scaled_pixmap = self.pixmap.scaled(self.image_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
             else:
                 self.pixmap = self.scaled_pixmap = None
             self.update()
         elif event.propertyName() == 'imageGeometry' and self.pixmap:
             self.scaled_pixmap = self.pixmap.scaled(self.image_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
             self.update()
         elif event.propertyName() == 'backgroundColor':
             self.update()
     return super(BackgroundFrame, self).event(event)
Exemplo n.º 25
0
 def event(self, event):
     if event.type() == QEvent.DynamicPropertyChange:
         if event.propertyName() == 'backgroundImage':
             self.pixmap = QPixmap()
             if self.backgroundImage and self.pixmap.load(Resources.get(self.backgroundImage)):
                 self.scaled_pixmap = self.pixmap.scaled(self.image_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
             else:
                 self.pixmap = self.scaled_pixmap = None
             self.update()
         elif event.propertyName() == 'imageGeometry' and self.pixmap:
             self.scaled_pixmap = self.pixmap.scaled(self.image_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
             self.update()
         elif event.propertyName() == 'backgroundColor':
             self.update()
     return super(BackgroundFrame, self).event(event)
Exemplo n.º 26
0
 def __init__(self, parent=None):
     super(ValidatingLineEdit, self).__init__(parent)
     self.invalid_entry_label = QLabel(self)
     self.invalid_entry_label.setFixedSize(18, 16)
     self.invalid_entry_label.setPixmap(QPixmap(Resources.get('icons/invalid16.png')))
     self.invalid_entry_label.setScaledContents(False)
     self.invalid_entry_label.setAlignment(Qt.AlignCenter)
     self.invalid_entry_label.setObjectName('invalid_entry_label')
     self.invalid_entry_label.hide()
     self.addTailWidget(self.invalid_entry_label)
     option = QStyleOptionFrame()
     self.initStyleOption(option)
     frame_width = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth, option, self)
     self.setMinimumHeight(self.invalid_entry_label.minimumHeight() + 2 + 2*frame_width)
     self.textChanged.connect(self._SH_TextChanged)
     self.text_correct = True
     self.text_allowed = True
     self.exceptions = set()
     self.regexp = re.compile(r'.*')
Exemplo n.º 27
0
 def __init__(self, parent=None, size=16):
     super(ClearButton, self).__init__(parent)
     self.setCursor(Qt.ArrowCursor)
     self.setFocusPolicy(Qt.NoFocus)
     self.setToolTip(u"Clear")
     self.setVisible(False)
     self.setMinimumSize(size+2, size+2)
     pixmap = QPixmap()
     if pixmap.load(Resources.get("icons/delete.svg")):
         self.icon = pixmap.scaled(size, size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
         # Use QImage because QPainter using a QPixmap does not support CompositionMode_Multiply -Dan
         image = self.icon.toImage()
         painter = QPainter(image)
         painter.setRenderHint(QPainter.Antialiasing, True)
         painter.setCompositionMode(QPainter.CompositionMode_Multiply)
         painter.drawPixmap(0, 0, self.icon)
         painter.end()
         self.icon_pressed = QPixmap(image)
     else:
         self.icon = self.icon_pressed = None
Exemplo n.º 28
0
 def __init__(self, model, parent=None):
     super(ServerToolsWindow, self).__init__(parent)
     with Resources.directory:
         self.setupUi()
     self.setWindowTitle('Blink Server Tools')
     self.setWindowIcon(QIcon(Resources.get('icons/blink48.png')))
     self.model = model
     self.model.rowsInserted.connect(self._SH_ModelChanged)
     self.model.rowsRemoved.connect(self._SH_ModelChanged)
     self.account_button.menu().triggered.connect(self._SH_AccountButtonMenuTriggered)
     self.back_button.clicked.connect(self._SH_BackButtonClicked)
     self.back_button.triggered.connect(self._SH_NavigationButtonTriggered)
     self.forward_button.clicked.connect(self._SH_ForwardButtonClicked)
     self.forward_button.triggered.connect(self._SH_NavigationButtonTriggered)
     self.home_button.clicked.connect(self._SH_HomeButtonClicked)
     self.web_view.loadStarted.connect(self._SH_WebViewLoadStarted)
     self.web_view.loadFinished.connect(self._SH_WebViewLoadFinished)
     self.web_view.titleChanged.connect(self._SH_WebViewTitleChanged)
     notification_center = NotificationCenter()
     notification_center.add_observer(self, name='SIPApplicationDidStart')
Exemplo n.º 29
0
 def __init__(self, model, parent=None):
     super(ServerToolsWindow, self).__init__(parent)
     with Resources.directory:
         self.setupUi()
     self.setWindowTitle('Blink Server Tools')
     self.setWindowIcon(QIcon(Resources.get('icons/blink48.png')))
     self.model = model
     self.model.rowsInserted.connect(self._SH_ModelChanged)
     self.model.rowsRemoved.connect(self._SH_ModelChanged)
     self.account_button.menu().triggered.connect(self._SH_AccountButtonMenuTriggered)
     self.back_button.clicked.connect(self._SH_BackButtonClicked)
     self.back_button.triggered.connect(self._SH_NavigationButtonTriggered)
     self.forward_button.clicked.connect(self._SH_ForwardButtonClicked)
     self.forward_button.triggered.connect(self._SH_NavigationButtonTriggered)
     self.home_button.clicked.connect(self._SH_HomeButtonClicked)
     self.web_view.loadStarted.connect(self._SH_WebViewLoadStarted)
     self.web_view.loadFinished.connect(self._SH_WebViewLoadFinished)
     self.web_view.titleChanged.connect(self._SH_WebViewTitleChanged)
     notification_center = NotificationCenter()
     notification_center.add_observer(self, name='SIPApplicationDidStart')
Exemplo n.º 30
0
 def __init__(self, parent=None, size=16):
     super(ClearButton, self).__init__(parent)
     self.setCursor(Qt.ArrowCursor)
     self.setFocusPolicy(Qt.NoFocus)
     self.setToolTip("Clear")
     self.setVisible(False)
     self.setMinimumSize(size + 2, size + 2)
     pixmap = QPixmap()
     if pixmap.load(Resources.get("icons/delete.svg")):
         self.icon = pixmap.scaled(size, size, Qt.KeepAspectRatio,
                                   Qt.SmoothTransformation)
         # Use QImage because QPainter using a QPixmap does not support CompositionMode_Multiply -Dan
         image = self.icon.toImage()
         painter = QPainter(image)
         painter.setRenderHint(QPainter.Antialiasing, True)
         painter.setCompositionMode(QPainter.CompositionMode_Multiply)
         painter.drawPixmap(0, 0, self.icon)
         painter.end()
         self.icon_pressed = QPixmap(image)
     else:
         self.icon = self.icon_pressed = None
Exemplo n.º 31
0
 def __init__(self, parent=None):
     super(ValidatingLineEdit, self).__init__(parent)
     self.invalid_entry_label = QLabel(self)
     self.invalid_entry_label.setFixedSize(18, 16)
     self.invalid_entry_label.setPixmap(
         QPixmap(Resources.get('icons/invalid16.png')))
     self.invalid_entry_label.setScaledContents(False)
     self.invalid_entry_label.setAlignment(Qt.AlignCenter)
     self.invalid_entry_label.setObjectName('invalid_entry_label')
     self.invalid_entry_label.hide()
     self.addTailWidget(self.invalid_entry_label)
     option = QStyleOptionFrame()
     self.initStyleOption(option)
     frame_width = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth,
                                            option, self)
     self.setMinimumHeight(self.invalid_entry_label.minimumHeight() + 2 +
                           2 * frame_width)
     self.textChanged.connect(self._SH_TextChanged)
     self.text_correct = True
     self.text_allowed = True
     self.exceptions = set()
     self.regexp = re.compile(r'.*')
Exemplo n.º 32
0
 def _SH_WebViewLoadFinished(self, load_ok):
     self.spinner.hide()
     if not load_ok:
         icon_path = Resources.get('icons/invalid.png')
         error_message = self.web_view.last_error or 'Unknown error'
         html = """
         <html>
          <head>
           <style>
             .icon    { width: 64px; height: 64px; float: left; }
             .message { margin-left: 74px; line-height: 64px; vertical-align: middle; }
           </style>
          </head>
          <body>
           <img class="icon" src="file:%s" />
           <div class="message">Failed to load web page: <b>%s</b></div>
          </body>
         </html>
         """ % (icon_path, error_message)
         self.web_view.blockSignals(True)
         self.web_view.setHtml(html)
         self.web_view.blockSignals(False)
     self._update_navigation_buttons()
Exemplo n.º 33
0
 def _SH_WebViewLoadFinished(self, load_ok):
     self.spinner.hide()
     if not load_ok:
         icon_path = Resources.get('icons/invalid.png')
         error_message = self.web_view.last_error or 'Unknown error'
         html = """
         <html>
          <head>
           <style>
             .icon    { width: 64px; height: 64px; float: left; }
             .message { margin-left: 74px; line-height: 64px; vertical-align: middle; }
           </style>
          </head>
          <body>
           <img class="icon" src="file:%s" />
           <div class="message">Failed to load web page: <b>%s</b></div>
          </body>
         </html>
         """ % (icon_path, error_message)
         self.web_view.blockSignals(True)
         self.web_view.setHtml(html)
         self.web_view.blockSignals(False)
     self._update_navigation_buttons()
Exemplo n.º 34
0
        if self.scale:
            self.update(self.transform.mapRect(QRect(x, y, w, h)).adjusted(-1, -1, 1, 1).intersected(self.rect()))
        else:
            self.update(x, y, w, h)

    def _SH_PasswordRequested(self, with_username):
        dialog = ScreensharingDialog(self)
        if with_username:
            username, password = dialog.get_credentials()
        else:
            username, password = None, dialog.get_password()
        self.client.username = username
        self.client.password = password


ui_class, base_class = uic.loadUiType(Resources.get('screensharing_dialog.ui'))

class ScreensharingDialog(base_class, ui_class):
    def __init__(self, parent=None):
        super(ScreensharingDialog, self).__init__(parent)
        with Resources.directory:
            self.setupUi(self)
        self.setWindowModality(Qt.WindowModal)
        parent.installEventFilter(self)

    def eventFilter(self, watched, event):
        if watched is self.parent() and event.type() in (QEvent.Close, QEvent.Hide):
            self.reject()
        return False

    def get_credentials(self):
Exemplo n.º 35
0
class HistoryEntry(object):
    phone_number_re = re.compile(r'^(?P<number>(0|00|\+)[1-9]\d{7,14})@')

    incoming_normal_icon = IconDescriptor(
        Resources.get('icons/arrow-inward-blue.svg'))
    outgoing_normal_icon = IconDescriptor(
        Resources.get('icons/arrow-outward-green.svg'))
    incoming_failed_icon = IconDescriptor(
        Resources.get('icons/arrow-inward-red.svg'))
    outgoing_failed_icon = IconDescriptor(
        Resources.get('icons/arrow-outward-red.svg'))

    def __init__(self,
                 direction,
                 name,
                 uri,
                 account_id,
                 call_time,
                 duration,
                 failed=False,
                 reason=None):
        self.direction = direction
        self.name = name
        self.uri = uri
        self.account_id = account_id
        self.call_time = call_time
        self.duration = duration
        self.failed = failed
        self.reason = reason

    def __reduce__(self):
        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):
        return self is other

    def __ne__(self, other):
        return self is not other

    def __lt__(self, other):
        return self.call_time < other.call_time

    def __le__(self, other):
        return self.call_time <= other.call_time

    def __gt__(self, other):
        return self.call_time > other.call_time

    def __ge__(self, other):
        return self.call_time >= other.call_time

    @property
    def icon(self):
        if self.failed:
            return self.incoming_failed_icon if self.direction == 'incoming' else self.outgoing_failed_icon
        else:
            return self.incoming_normal_icon if self.direction == 'incoming' else self.outgoing_normal_icon

    @property
    def text(self):
        result = unicode(self.name or self.uri)
        if self.call_time:
            call_time = self.call_time.astimezone(tzlocal())
            call_date = call_time.date()
            today = date.today()
            days = (today - call_date).days
            if call_date == today:
                result += call_time.strftime(" at %H:%M")
            elif days == 1:
                result += call_time.strftime(" Yesterday at %H:%M")
            elif days < 7:
                result += call_time.strftime(" on %A")
            elif call_date.year == today.year:
                result += call_time.strftime(" on %B %d")
            else:
                result += call_time.strftime(" on %Y-%m-%d")
        if self.duration:
            seconds = int(self.duration.total_seconds())
            if seconds >= 3600:
                result += """ (%dh%02d'%02d")""" % (seconds / 3600,
                                                    (seconds % 3600) / 60,
                                                    seconds % 60)
            else:
                result += """ (%d'%02d")""" % (seconds / 60, seconds % 60)
        elif self.reason:
            result += ' (%s)' % self.reason.title()
        return result

    @classmethod
    def from_session(cls, session):
        if session.start_time is None and session.end_time is not None:
            # Session may have anded before it fully started
            session.start_time = session.end_time
        call_time = session.start_time or ISOTimestamp.now()
        if session.start_time and session.end_time:
            duration = session.end_time - session.start_time
        else:
            duration = None
        remote_uri = '%s@%s' % (session.remote_identity.uri.user,
                                session.remote_identity.uri.host)
        match = cls.phone_number_re.match(remote_uri)
        if match:
            remote_uri = match.group('number')
        try:
            contact = next(contact
                           for contact in AddressbookManager().get_contacts()
                           if remote_uri in (addr.uri
                                             for addr in contact.uris))
        except StopIteration:
            display_name = session.remote_identity.display_name
        else:
            display_name = contact.name
        return cls(session.direction, display_name, remote_uri,
                   unicode(session.account.id), call_time, duration)
Exemplo n.º 36
0
            source_model = model.sourceModel()
            account_index = source_model.accounts.index(account)
            self.setCurrentIndex(
                model.mapFromSource(source_model.index(account_index)).row())

    def _NH_SIPAccountManagerDidChangeDefaultAccount(self, notification):
        account = notification.data.account
        if account is not None:
            model = self.model()
            source_model = model.sourceModel()
            account_index = source_model.accounts.index(account)
            self.setCurrentIndex(
                model.mapFromSource(source_model.index(account_index)).row())


ui_class, base_class = uic.loadUiType(Resources.get('add_account.ui'))


class AddAccountDialog(base_class, ui_class):
    __metaclass__ = QSingleton

    implements(IObserver)

    def __init__(self, parent=None):
        super(AddAccountDialog, self).__init__(parent)
        with Resources.directory:
            self.setupUi(self)
        self.background_frame.setStyleSheet("")
        self.button_group = QButtonGroup(self)
        self.button_group.setObjectName("button_group")
        self.button_group.addButton(
Exemplo n.º 37
0
 a:link  { text-decoration: none; color: #1f487f; }
</style>
</head>
<body>
<table width="100%" cellspacing="2" cellpadding="0" border="0">
 <tr><td class="name" align="right">AG Projects</td><td align="left"><a href="http://ag-projects.com/">http://ag-projects.com/</a></td></tr>
 <tr><td class="name" align="right">NLnet Foundation</td><td align="left"><a href="http://nlnet.nl/">http://nlnet.nl/</a></td></tr>
 <tr><td class="name" align="right">IETF Community</td><td align="left"><a href="http://ietf.org/">http://ietf.org/</a></td></tr>
 <tr><td class="name" align="right">SIP Simple Client</td><td align="left"><a href="http://sipsimpleclient.org/">http://sipsimpleclient.org/</a></td></tr>
</table>
</body>
</html>
"""


ui_class, base_class = uic.loadUiType(Resources.get('about_panel.ui'))

class AboutPanel(base_class, ui_class):
    __metaclass__ = QSingleton

    def __init__(self, parent=None):
        super(AboutPanel, self).__init__(parent)

        with Resources.directory:
            self.setupUi(self)

        self.version.setText(u'Version %s\n%s' % (__version__, __date__))

        credits_width = self.credits_text.fontMetrics().width("NLNET Foundation" + "http://sipsimpleclient.org") + 40
        self.credits_text.setFixedWidth(credits_width)
        self.credits_text.document().documentLayout().documentSizeChanged.connect(self._credits_size_changed)
Exemplo n.º 38
0
    def setupUi(self):
        super(ScreensharingToolbox, self).setupUi(self)

        # fix the SVG icons, as the generated code loads them as pixmaps, losing their ability to scale -Dan
        scale_icon = QIcon()
        scale_icon.addFile(Resources.get('icons/scale.svg'),
                           mode=QIcon.Normal,
                           state=QIcon.Off)
        viewonly_icon = QIcon()
        viewonly_icon.addFile(Resources.get('icons/viewonly.svg'),
                              mode=QIcon.Normal,
                              state=QIcon.Off)
        screenshot_icon = QIcon()
        screenshot_icon.addFile(Resources.get('icons/screenshot.svg'),
                                mode=QIcon.Normal,
                                state=QIcon.Off)
        fullscreen_icon = QIcon()
        fullscreen_icon.addFile(Resources.get('icons/fullscreen.svg'),
                                mode=QIcon.Normal,
                                state=QIcon.Off)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'),
                                mode=QIcon.Normal,
                                state=QIcon.On)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'),
                                mode=QIcon.Active,
                                state=QIcon.On)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'),
                                mode=QIcon.Disabled,
                                state=QIcon.On)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'),
                                mode=QIcon.Selected,
                                state=QIcon.On)
        minimize_icon = QIcon()
        minimize_icon.addFile(Resources.get('icons/minimize.svg'),
                              mode=QIcon.Normal,
                              state=QIcon.Off)
        minimize_icon.addFile(Resources.get('icons/minimize-active.svg'),
                              mode=QIcon.Active,
                              state=QIcon.Off)
        close_icon = QIcon()
        close_icon.addFile(Resources.get('icons/close.svg'),
                           mode=QIcon.Normal,
                           state=QIcon.Off)
        close_icon.addFile(Resources.get('icons/close-active.svg'),
                           mode=QIcon.Active,
                           state=QIcon.Off)

        self.scale_action.setIcon(scale_icon)
        self.viewonly_action.setIcon(viewonly_icon)
        self.screenshot_action.setIcon(screenshot_icon)
        self.fullscreen_action.setIcon(fullscreen_icon)
        self.minimize_action.setIcon(minimize_icon)
        self.close_action.setIcon(close_icon)

        self.scale_button.setIcon(scale_icon)
        self.viewonly_button.setIcon(viewonly_icon)
        self.screenshot_button.setIcon(screenshot_icon)
        self.fullscreen_button.setIcon(fullscreen_icon)
        self.minimize_button.setIcon(minimize_icon)
        self.close_button.setIcon(close_icon)

        self.scale_button.setDefaultAction(self.scale_action)
        self.viewonly_button.setDefaultAction(self.viewonly_action)
        self.screenshot_button.setDefaultAction(self.screenshot_action)
        self.fullscreen_button.setDefaultAction(self.fullscreen_action)
        self.minimize_button.setDefaultAction(self.minimize_action)
        self.close_button.setDefaultAction(self.close_action)

        self.color_depth_button.clear()
        self.color_depth_button.addItem('Default Color Depth', ServerDefault)
        self.color_depth_button.addItem('TrueColor (24 bits)', TrueColor)
        self.color_depth_button.addItem('HighColor (16 bits)', HighColor)
        self.color_depth_button.addItem('LowColor (8 bits)', LowColor)
Exemplo n.º 39
0
 def mouseReleaseEvent(self, event):
     if event.button() == Qt.LeftButton and self.rect().contains(event.pos()):
         filename = unicode(QFileDialog.getOpenFileName(self, u'Select Icon', self.last_icon_directory, u"Images (*.png *.tiff *.jpg *.xmp *.svg)"))
         if filename:
             self.last_icon_directory = os.path.dirname(filename)
             self.filename = filename if os.path.realpath(filename) != os.path.realpath(Resources.get(self.default_icon)) else None
     super(IconSelector, self).mouseReleaseEvent(event)
Exemplo n.º 40
0
class PresenceManager(object):
    def __init__(self):
        self.publication_handler = PresencePublicationHandler()
        self.subscription_handler = PresenceSubscriptionHandler()

    def start(self):
        self.publication_handler.start()
        self.subscription_handler.start()

    def stop(self):
        self.publication_handler.stop()
        self.subscription_handler.stop()


ui_class, base_class = uic.loadUiType(Resources.get('pending_watcher.ui'))


class PendingWatcherDialog(base_class, ui_class):
    def __init__(self, account, uri, display_name, parent=None):
        super(PendingWatcherDialog, self).__init__(parent)
        self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_DeleteOnClose)
        with Resources.directory:
            self.setupUi(self)
        default_font_size = self.uri_label.fontInfo().pointSizeF()
        name_font_size = limit(default_font_size + 3, max=14)
        font = self.name_label.font()
        font.setPointSizeF(name_font_size)
        self.name_label.setFont(font)
        addressbook_manager = addressbook.AddressbookManager()
Exemplo n.º 41
0
from blink.configuration.account import AccountExtension, BonjourAccountExtension
from blink.configuration.addressbook import ContactExtension, GroupExtension
from blink.configuration.settings import SIPSimpleSettingsExtension
from blink.logging import LogManager
from blink.mainwindow import MainWindow
from blink.presence import PresenceManager
from blink.resources import ApplicationData, Resources
from blink.sessions import SessionManager
from blink.update import UpdateManager
from blink.util import QSingleton, run_in_gui_thread

__all__ = ['Blink']

if hasattr(sys, 'frozen'):
    import httplib2
    httplib2.CA_CERTS = os.environ['SSL_CERT_FILE'] = Resources.get(
        'tls/cacerts.pem')
    makedirs(ApplicationData.get('logs'))
    sys.stdout.file = ApplicationData.get('logs/output.log')


class IPAddressMonitor(object):
    """
    An object which monitors the IP address used for the default route of the
    host and posts a SystemIPAddressDidChange notification when a change is
    detected.
    """
    def __init__(self):
        self.greenlet = None

    @run_in_green_thread
    def start(self):
Exemplo n.º 42
0
from blink.presence import PresenceManager
from blink.resources import ApplicationData, Resources
from blink.sessions import SessionManager
from blink.update import UpdateManager
from blink.util import QSingleton, run_in_gui_thread


__all__ = ["Blink"]


if hasattr(sys, "frozen"):
    makedirs(ApplicationData.get("logs"))
    sys.stdout.file = open(ApplicationData.get("logs/output.log"), "a", 0)
    import httplib2

    httplib2.CA_CERTS = os.environ["SSL_CERT_FILE"] = Resources.get("tls/cacerts.pem")


class IPAddressMonitor(object):
    """
    An object which monitors the IP address used for the default route of the
    host and posts a SystemIPAddressDidChange notification when a change is
    detected.
    """

    def __init__(self):
        self.greenlet = None

    @run_in_green_thread
    def start(self):
        notification_center = NotificationCenter()
Exemplo n.º 43
0
from blink.filetransferwindow import FileTransferWindow
from blink.history import HistoryManager
from blink.preferences import PreferencesWindow
from blink.sessions import ConferenceDialog, SessionManager, AudioSessionModel, StreamDescription
from blink.configuration.datatypes import IconDescriptor, FileURL, PresenceState
from blink.configuration.settings import BlinkSettings
from blink.presence import PendingWatcherDialog
from blink.resources import ApplicationData, IconManager, Resources
from blink.util import run_in_gui_thread
from blink.widgets.buttons import AccountState, SwitchViewButton


__all__ = ['MainWindow']


ui_class, base_class = uic.loadUiType(Resources.get('blink.ui'))


@implementer(IObserver)
class MainWindow(base_class, ui_class):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.saved_account_state = None

        notification_center = NotificationCenter()
        notification_center.add_observer(self, name='SIPApplicationWillStart')
        notification_center.add_observer(self, name='SIPApplicationDidStart')
        notification_center.add_observer(self, name='SIPAccountGotMessageSummary')
        notification_center.add_observer(self, name='SIPAccountGotPendingWatcher')
        notification_center.add_observer(self, name='BlinkSessionNewOutgoing')
Exemplo n.º 44
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.saved_account_state = None

        notification_center = NotificationCenter()
        notification_center.add_observer(self, name='SIPApplicationWillStart')
        notification_center.add_observer(self, name='SIPApplicationDidStart')
        notification_center.add_observer(self, name='SIPAccountGotMessageSummary')
        notification_center.add_observer(self, name='SIPAccountGotPendingWatcher')
        notification_center.add_observer(self, name='BlinkSessionNewOutgoing')
        notification_center.add_observer(self, name='BlinkSessionDidReinitializeForOutgoing')
        notification_center.add_observer(self, name='BlinkSessionTransferNewOutgoing')
        notification_center.add_observer(self, name='BlinkFileTransferNewIncoming')
        notification_center.add_observer(self, name='BlinkFileTransferNewOutgoing')
        notification_center.add_observer(self, sender=AccountManager())

        icon_manager = IconManager()

        self.pending_watcher_dialogs = []

        self.mwi_icons = [QIcon(Resources.get('icons/mwi-%d.png' % i)) for i in range(0, 11)]
        self.mwi_icons.append(QIcon(Resources.get('icons/mwi-many.png')))

        with Resources.directory:
            self.setupUi()

        self.setWindowTitle('Blink')

        geometry = QSettings().value("main_window/geometry")
        if geometry:
            self.restoreGeometry(geometry)

        self.default_icon_path = Resources.get('icons/default-avatar.png')
        self.default_icon = QIcon(self.default_icon_path)
        self.last_icon_directory = Path('~').normalized
        self.set_user_icon(icon_manager.get('avatar'))

        self.active_sessions_label.hide()
        self.enable_call_buttons(False)
        self.conference_button.setEnabled(False)
        self.hangup_all_button.setEnabled(False)
        self.sip_server_settings_action.setEnabled(False)
        self.search_for_people_action.setEnabled(False)
        self.history_on_server_action.setEnabled(False)
        self.main_view.setCurrentWidget(self.contacts_panel)
        self.contacts_view.setCurrentWidget(self.contact_list_panel)
        self.search_view.setCurrentWidget(self.search_list_panel)

        # System tray
        if QSystemTrayIcon.isSystemTrayAvailable():
            self.system_tray_icon = QSystemTrayIcon(QIcon(Resources.get('icons/blink.png')), self)
            self.system_tray_icon.activated.connect(self._SH_SystemTrayIconActivated)
            menu = QMenu(self)
            menu.addAction("Show", self._AH_SystemTrayShowWindow)
            menu.addAction(QIcon(Resources.get('icons/application-exit.png')), "Quit", self._AH_QuitActionTriggered)
            self.system_tray_icon.setContextMenu(menu)
            self.system_tray_icon.show()
        else:
            self.system_tray_icon = None

        # Accounts
        self.account_model = AccountModel(self)
        self.enabled_account_model = ActiveAccountModel(self.account_model, self)
        self.server_tools_account_model = ServerToolsAccountModel(self.account_model, self)
        self.identity.setModel(self.enabled_account_model)

        # Contacts
        self.contact_model = ContactModel(self)
        self.contact_search_model = ContactSearchModel(self.contact_model, self)
        self.contact_list.setModel(self.contact_model)
        self.search_list.setModel(self.contact_search_model)

        # Sessions (audio)
        self.session_model = AudioSessionModel(self)
        self.session_list.setModel(self.session_model)
        self.session_list.selectionModel().selectionChanged.connect(self._SH_SessionListSelectionChanged)

        # History
        self.history_manager = HistoryManager()

        # Windows, dialogs and panels
        self.about_panel = AboutPanel(self)
        self.conference_dialog = ConferenceDialog(self)
        self.contact_editor_dialog = ContactEditorDialog(self)
        self.filetransfer_window = FileTransferWindow()
        self.preferences_window = PreferencesWindow(self.account_model, None)
        self.server_tools_window = ServerToolsWindow(self.server_tools_account_model, None)

        # Signals
        self.account_state.stateChanged.connect(self._SH_AccountStateChanged)
        self.account_state.clicked.connect(self._SH_AccountStateClicked)
        self.activity_note.editingFinished.connect(self._SH_ActivityNoteEditingFinished)
        self.add_contact_button.clicked.connect(self._SH_AddContactButtonClicked)
        self.add_search_contact_button.clicked.connect(self._SH_AddContactButtonClicked)
        self.audio_call_button.clicked.connect(self._SH_AudioCallButtonClicked)
        self.video_call_button.clicked.connect(self._SH_VideoCallButtonClicked)
        self.chat_session_button.clicked.connect(self._SH_ChatSessionButtonClicked)
        self.back_to_contacts_button.clicked.connect(self.search_box.clear)  # this can be set in designer -Dan
        self.conference_button.makeConference.connect(self._SH_MakeConference)
        self.conference_button.breakConference.connect(self._SH_BreakConference)

        self.contact_list.selectionModel().selectionChanged.connect(self._SH_ContactListSelectionChanged)
        self.contact_model.itemsAdded.connect(self._SH_ContactModelAddedItems)
        self.contact_model.itemsRemoved.connect(self._SH_ContactModelRemovedItems)

        self.display_name.editingFinished.connect(self._SH_DisplayNameEditingFinished)
        self.hangup_all_button.clicked.connect(self._SH_HangupAllButtonClicked)

        self.identity.activated[int].connect(self._SH_IdentityChanged)
        self.identity.currentIndexChanged[int].connect(self._SH_IdentityCurrentIndexChanged)

        self.mute_button.clicked.connect(self._SH_MuteButtonClicked)

        self.search_box.textChanged.connect(self._SH_SearchBoxTextChanged)
        self.search_box.returnPressed.connect(self._SH_SearchBoxReturnPressed)
        self.search_box.shortcut.activated.connect(self.search_box.setFocus)

        self.search_list.selectionModel().selectionChanged.connect(self._SH_SearchListSelectionChanged)

        self.server_tools_account_model.rowsInserted.connect(self._SH_ServerToolsAccountModelChanged)
        self.server_tools_account_model.rowsRemoved.connect(self._SH_ServerToolsAccountModelChanged)

        self.session_model.sessionAdded.connect(self._SH_AudioSessionModelAddedSession)
        self.session_model.sessionRemoved.connect(self._SH_AudioSessionModelRemovedSession)
        self.session_model.structureChanged.connect(self._SH_AudioSessionModelChangedStructure)

        self.silent_button.clicked.connect(self._SH_SilentButtonClicked)
        self.switch_view_button.viewChanged.connect(self._SH_SwitchViewButtonChangedView)

        # Blink menu actions
        self.about_action.triggered.connect(self.about_panel.show)
        self.add_account_action.triggered.connect(self.preferences_window.show_add_account_dialog)
        self.manage_accounts_action.triggered.connect(self.preferences_window.show_for_accounts)
        self.help_action.triggered.connect(partial(QDesktopServices.openUrl, QUrl('http://icanblink.com/help/')))
        self.preferences_action.triggered.connect(self.preferences_window.show)
        self.auto_accept_chat_action.triggered.connect(self._AH_AutoAcceptChatActionTriggered)
        self.received_messages_sound_action.triggered.connect(self._AH_ReceivedMessagesSoundActionTriggered)
        self.answering_machine_action.triggered.connect(self._AH_EnableAnsweringMachineActionTriggered)
        self.release_notes_action.triggered.connect(partial(QDesktopServices.openUrl, QUrl('http://icanblink.com/changelog/')))
        self.quit_action.triggered.connect(self._AH_QuitActionTriggered)

        # Call menu actions
        self.redial_action.triggered.connect(self._AH_RedialActionTriggered)
        self.join_conference_action.triggered.connect(self.conference_dialog.show)
        self.history_menu.aboutToShow.connect(self._SH_HistoryMenuAboutToShow)
        self.history_menu.triggered.connect(self._AH_HistoryMenuTriggered)
        self.output_devices_group.triggered.connect(self._AH_AudioOutputDeviceChanged)
        self.input_devices_group.triggered.connect(self._AH_AudioInputDeviceChanged)
        self.alert_devices_group.triggered.connect(self._AH_AudioAlertDeviceChanged)
        self.video_devices_group.triggered.connect(self._AH_VideoDeviceChanged)
        self.mute_action.triggered.connect(self._SH_MuteButtonClicked)
        self.silent_action.triggered.connect(self._SH_SilentButtonClicked)

        # Tools menu actions
        self.sip_server_settings_action.triggered.connect(self._AH_SIPServerSettings)
        self.search_for_people_action.triggered.connect(self._AH_SearchForPeople)
        self.history_on_server_action.triggered.connect(self._AH_HistoryOnServer)
        self.google_contacts_action.triggered.connect(self._AH_GoogleContactsActionTriggered)

        # Window menu actions
        self.chat_window_action.triggered.connect(self._AH_ChatWindowActionTriggered)
        self.transfers_window_action.triggered.connect(self._AH_TransfersWindowActionTriggered)
        self.logs_window_action.triggered.connect(self._AH_LogsWindowActionTriggered)
        self.received_files_window_action.triggered.connect(self._AH_ReceivedFilesWindowActionTriggered)
        self.screenshots_window_action.triggered.connect(self._AH_ScreenshotsWindowActionTriggered)
Exemplo n.º 45
0
        if account is not None:
            model = self.model()
            source_model = model.sourceModel()
            account_index = source_model.accounts.index(account)
            self.setCurrentIndex(model.mapFromSource(source_model.index(account_index)).row())

    def _NH_SIPAccountManagerDidChangeDefaultAccount(self, notification):
        account = notification.data.account
        if account is not None:
            model = self.model()
            source_model = model.sourceModel()
            account_index = source_model.accounts.index(account)
            self.setCurrentIndex(model.mapFromSource(source_model.index(account_index)).row())


ui_class, base_class = uic.loadUiType(Resources.get("add_account.ui"))


class AddAccountDialog(base_class, ui_class):
    __metaclass__ = QSingleton

    implements(IObserver)

    def __init__(self, parent=None):
        super(AddAccountDialog, self).__init__(parent)
        with Resources.directory:
            self.setupUi(self)
        self.background_frame.setStyleSheet("")
        self.button_group = QButtonGroup(self)
        self.button_group.setObjectName("button_group")
        self.button_group.addButton(self.add_account_button, self.panel_view.indexOf(self.add_account_panel))
Exemplo n.º 46
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.saved_account_state = None

        notification_center = NotificationCenter()
        notification_center.add_observer(self, name='SIPApplicationWillStart')
        notification_center.add_observer(self, name='SIPApplicationDidStart')
        notification_center.add_observer(self, name='SIPAccountGotMessageSummary')
        notification_center.add_observer(self, name='SIPAccountGotPendingWatcher')
        notification_center.add_observer(self, name='BlinkSessionNewOutgoing')
        notification_center.add_observer(self, name='BlinkSessionDidReinitializeForOutgoing')
        notification_center.add_observer(self, name='FileTransferNewIncoming')
        notification_center.add_observer(self, name='FileTransferNewOutgoing')
        notification_center.add_observer(self, sender=AccountManager())

        icon_manager = IconManager()

        self.pending_watcher_dialogs = []

        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()

        self.setWindowTitle('Blink')
        self.setWindowIconText('Blink')

        geometry = QSettings().value("main_window/geometry")
        if geometry:
            self.restoreGeometry(geometry)

        self.default_icon_path = Resources.get('icons/default-avatar.png')
        self.default_icon = QIcon(self.default_icon_path)
        self.last_icon_directory = Path('~').normalized
        self.set_user_icon(icon_manager.get('avatar'))

        self.active_sessions_label.hide()
        self.enable_call_buttons(False)
        self.conference_button.setEnabled(False)
        self.hangup_all_button.setEnabled(False)
        self.sip_server_settings_action.setEnabled(False)
        self.search_for_people_action.setEnabled(False)
        self.history_on_server_action.setEnabled(False)
        self.main_view.setCurrentWidget(self.contacts_panel)
        self.contacts_view.setCurrentWidget(self.contact_list_panel)
        self.search_view.setCurrentWidget(self.search_list_panel)

        # System tray
        if QSystemTrayIcon.isSystemTrayAvailable() and not os.getenv('XDG_CURRENT_DESKTOP', '').lower().startswith('unity'):
            self.system_tray_icon = QSystemTrayIcon(QIcon(Resources.get('icons/blink.png')), self)
            self.system_tray_icon.activated.connect(self._SH_SystemTrayIconActivated)
            menu = QMenu(self)
            menu.addAction(QAction("Show", self, triggered=self._AH_SystemTrayShowWindow))
            menu.addAction(QAction(QIcon(Resources.get('icons/application-exit.png')), "Quit", self, triggered=self._AH_QuitActionTriggered))
            self.system_tray_icon.setContextMenu(menu)
            self.system_tray_icon.show()
        else:
            self.system_tray_icon = None

        # Accounts
        self.account_model = AccountModel(self)
        self.enabled_account_model = ActiveAccountModel(self.account_model, self)
        self.server_tools_account_model = ServerToolsAccountModel(self.account_model, self)
        self.identity.setModel(self.enabled_account_model)

        # Contacts
        self.contact_model = ContactModel(self)
        self.contact_search_model = ContactSearchModel(self.contact_model, self)
        self.contact_list.setModel(self.contact_model)
        self.search_list.setModel(self.contact_search_model)

        # Sessions (audio)
        self.session_model = AudioSessionModel(self)
        self.session_list.setModel(self.session_model)
        self.session_list.selectionModel().selectionChanged.connect(self._SH_SessionListSelectionChanged)

        # History
        self.history_manager = HistoryManager()

        # Windows, dialogs and panels
        self.about_panel = AboutPanel(self)
        self.conference_dialog = ConferenceDialog(self)
        self.contact_editor_dialog = ContactEditorDialog(self)
        self.google_contacts_dialog = GoogleContactsDialog(self)
        self.filetransfer_window = FileTransferWindow()
        self.preferences_window = PreferencesWindow(self.account_model, None)
        self.server_tools_window = ServerToolsWindow(self.server_tools_account_model, None)

        # Signals
        self.account_state.stateChanged.connect(self._SH_AccountStateChanged)
        self.account_state.clicked.connect(self._SH_AccountStateClicked)
        self.activity_note.editingFinished.connect(self._SH_ActivityNoteEditingFinished)
        self.add_contact_button.clicked.connect(self._SH_AddContactButtonClicked)
        self.add_search_contact_button.clicked.connect(self._SH_AddContactButtonClicked)
        self.audio_call_button.clicked.connect(self._SH_AudioCallButtonClicked)
        self.video_call_button.clicked.connect(self._SH_VideoCallButtonClicked)
        self.chat_session_button.clicked.connect(self._SH_ChatSessionButtonClicked)
        self.back_to_contacts_button.clicked.connect(self.search_box.clear) # this can be set in designer -Dan
        self.conference_button.makeConference.connect(self._SH_MakeConference)
        self.conference_button.breakConference.connect(self._SH_BreakConference)

        self.contact_list.selectionModel().selectionChanged.connect(self._SH_ContactListSelectionChanged)
        self.contact_model.itemsAdded.connect(self._SH_ContactModelAddedItems)
        self.contact_model.itemsRemoved.connect(self._SH_ContactModelRemovedItems)

        self.display_name.editingFinished.connect(self._SH_DisplayNameEditingFinished)
        self.hangup_all_button.clicked.connect(self._SH_HangupAllButtonClicked)

        self.identity.activated[int].connect(self._SH_IdentityChanged)
        self.identity.currentIndexChanged[int].connect(self._SH_IdentityCurrentIndexChanged)

        self.mute_button.clicked.connect(self._SH_MuteButtonClicked)

        self.search_box.textChanged.connect(self._SH_SearchBoxTextChanged)
        self.search_box.returnPressed.connect(self._SH_SearchBoxReturnPressed)
        self.search_box.shortcut.activated.connect(self.search_box.setFocus)

        self.search_list.selectionModel().selectionChanged.connect(self._SH_SearchListSelectionChanged)

        self.server_tools_account_model.rowsInserted.connect(self._SH_ServerToolsAccountModelChanged)
        self.server_tools_account_model.rowsRemoved.connect(self._SH_ServerToolsAccountModelChanged)

        self.session_model.sessionAdded.connect(self._SH_AudioSessionModelAddedSession)
        self.session_model.sessionRemoved.connect(self._SH_AudioSessionModelRemovedSession)
        self.session_model.structureChanged.connect(self._SH_AudioSessionModelChangedStructure)

        self.silent_button.clicked.connect(self._SH_SilentButtonClicked)
        self.switch_view_button.viewChanged.connect(self._SH_SwitchViewButtonChangedView)

        # Blink menu actions
        self.about_action.triggered.connect(self.about_panel.show)
        self.add_account_action.triggered.connect(self.preferences_window.show_add_account_dialog)
        self.manage_accounts_action.triggered.connect(self.preferences_window.show_for_accounts)
        self.help_action.triggered.connect(partial(QDesktopServices.openUrl, QUrl(u'http://icanblink.com/help-qt.phtml')))
        self.preferences_action.triggered.connect(self.preferences_window.show)
        self.auto_accept_chat_action.triggered.connect(self._AH_AutoAcceptChatActionTriggered)
        self.received_messages_sound_action.triggered.connect(self._AH_ReceivedMessagesSoundActionTriggered)
        self.answering_machine_action.triggered.connect(self._AH_EnableAnsweringMachineActionTriggered)
        self.release_notes_action.triggered.connect(partial(QDesktopServices.openUrl, QUrl(u'http://icanblink.com/changelog-qt.phtml')))
        self.quit_action.triggered.connect(self._AH_QuitActionTriggered)

        # Call menu actions
        self.redial_action.triggered.connect(self._AH_RedialActionTriggered)
        self.join_conference_action.triggered.connect(self.conference_dialog.show)
        self.history_menu.aboutToShow.connect(self._SH_HistoryMenuAboutToShow)
        self.history_menu.triggered.connect(self._AH_HistoryMenuTriggered)
        self.output_devices_group.triggered.connect(self._AH_AudioOutputDeviceChanged)
        self.input_devices_group.triggered.connect(self._AH_AudioInputDeviceChanged)
        self.alert_devices_group.triggered.connect(self._AH_AudioAlertDeviceChanged)
        self.video_devices_group.triggered.connect(self._AH_VideoDeviceChanged)
        self.mute_action.triggered.connect(self._SH_MuteButtonClicked)
        self.silent_action.triggered.connect(self._SH_SilentButtonClicked)

        # Tools menu actions
        self.sip_server_settings_action.triggered.connect(self._AH_SIPServerSettings)
        self.search_for_people_action.triggered.connect(self._AH_SearchForPeople)
        self.history_on_server_action.triggered.connect(self._AH_HistoryOnServer)

        # Window menu actions
        self.chat_window_action.triggered.connect(self._AH_ChatWindowActionTriggered)
        self.transfers_window_action.triggered.connect(self._AH_TransfersWindowActionTriggered)
        self.logs_window_action.triggered.connect(self._AH_LogsWindowActionTriggered)
        self.received_files_window_action.triggered.connect(self._AH_ReceivedFilesWindowActionTriggered)
        self.screenshots_window_action.triggered.connect(self._AH_ScreenshotsWindowActionTriggered)
Exemplo n.º 47
0
class PresenceManager(object):

    def __init__(self):
        self.publication_handler = PresencePublicationHandler()
        self.subscription_handler = PresenceSubscriptionHandler()

    def start(self):
        self.publication_handler.start()
        self.subscription_handler.start()

    def stop(self):
        self.publication_handler.stop()
        self.subscription_handler.stop()


ui_class, base_class = uic.loadUiType(Resources.get('pending_watcher.ui'))

class PendingWatcherDialog(base_class, ui_class):
    def __init__(self, account, uri, display_name, parent=None):
        super(PendingWatcherDialog, self).__init__(parent)
        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_DeleteOnClose)
        with Resources.directory:
            self.setupUi(self)
        addressbook_manager = addressbook.AddressbookManager()
        try:
            self.contact = next(contact for contact in addressbook_manager.get_contacts() if uri in (addr.uri for addr in contact.uris))
        except StopIteration:
            self.contact = None
        else:
            display_name = self.contact.name
Exemplo n.º 48
0
    def setupUi(self):
        super(ScreensharingToolbox, self).setupUi(self)

        # fix the SVG icons, as the generated code loads them as pixmaps, losing their ability to scale -Dan
        scale_icon = QIcon()
        scale_icon.addFile(Resources.get('icons/scale.svg'), mode=QIcon.Normal, state=QIcon.Off)
        viewonly_icon = QIcon()
        viewonly_icon.addFile(Resources.get('icons/viewonly.svg'), mode=QIcon.Normal, state=QIcon.Off)
        screenshot_icon = QIcon()
        screenshot_icon.addFile(Resources.get('icons/screenshot.svg'), mode=QIcon.Normal, state=QIcon.Off)
        fullscreen_icon = QIcon()
        fullscreen_icon.addFile(Resources.get('icons/fullscreen.svg'), mode=QIcon.Normal, state=QIcon.Off)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Normal, state=QIcon.On)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Active, state=QIcon.On)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Disabled, state=QIcon.On)
        fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Selected, state=QIcon.On)
        minimize_icon = QIcon()
        minimize_icon.addFile(Resources.get('icons/minimize.svg'), mode=QIcon.Normal, state=QIcon.Off)
        minimize_icon.addFile(Resources.get('icons/minimize-active.svg'), mode=QIcon.Active, state=QIcon.Off)
        close_icon = QIcon()
        close_icon.addFile(Resources.get('icons/close.svg'), mode=QIcon.Normal, state=QIcon.Off)
        close_icon.addFile(Resources.get('icons/close-active.svg'), mode=QIcon.Active, state=QIcon.Off)

        self.scale_action.setIcon(scale_icon)
        self.viewonly_action.setIcon(viewonly_icon)
        self.screenshot_action.setIcon(screenshot_icon)
        self.fullscreen_action.setIcon(fullscreen_icon)
        self.minimize_action.setIcon(minimize_icon)
        self.close_action.setIcon(close_icon)

        self.scale_button.setIcon(scale_icon)
        self.viewonly_button.setIcon(viewonly_icon)
        self.screenshot_button.setIcon(screenshot_icon)
        self.fullscreen_button.setIcon(fullscreen_icon)
        self.minimize_button.setIcon(minimize_icon)
        self.close_button.setIcon(close_icon)

        self.scale_button.setDefaultAction(self.scale_action)
        self.viewonly_button.setDefaultAction(self.viewonly_action)
        self.screenshot_button.setDefaultAction(self.screenshot_action)
        self.fullscreen_button.setDefaultAction(self.fullscreen_action)
        self.minimize_button.setDefaultAction(self.minimize_action)
        self.close_button.setDefaultAction(self.close_action)

        self.color_depth_button.clear()
        self.color_depth_button.addItem('Default Color Depth', ServerDefault)
        self.color_depth_button.addItem('TrueColor (24 bits)', TrueColor)
        self.color_depth_button.addItem('HighColor (16 bits)', HighColor)
        self.color_depth_button.addItem('LowColor (8 bits)', LowColor)
Exemplo n.º 49
0
import re

from PyQt5 import uic
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtWidgets import QStyle, QStyleOption, QStylePainter

from blink.resources import Resources
from blink.sessions import SMPVerification


__all__ = ['OTRWidget']


ui_class, base_class = uic.loadUiType(Resources.get('otr_widget.ui'))


class OTRWidget(base_class, ui_class):
    closed = pyqtSignal()
    nameChanged = pyqtSignal()
    statusChanged = pyqtSignal()

    color_table = {'green': 'hsv(100, 85%, 100%)', 'orange': 'hsv(20, 85%, 100%)'}

    def __init__(self, parent=None):
        super(OTRWidget, self).__init__(parent)
        with Resources.directory:
            self.setupUi(self)
        self.__dict__.update(peer_verified=False, smp_status=SMPVerification.Unavailable)  # interdependent properties (they need to preexist as their setters read each other)
        self.peer_name = ''
        self.peer_verified = False
Exemplo n.º 50
0
class AccountState(StateButton):
    Invisible = PresenceState('Invisible', '#efedeb',
                              Resources.get('icons/state-invisible.svg'))
    Available = PresenceState('Available', '#00ff00',
                              Resources.get('icons/state-available.svg'))
    Away = PresenceState('Away', '#ffff00',
                         Resources.get('icons/state-away.svg'))
    Busy = PresenceState('Busy', '#ff0000',
                         Resources.get('icons/state-busy.svg'))

    stateChanged = pyqtSignal()

    history_size = 7

    def __init__(self, parent=None):
        super(AccountState, self).__init__(parent)
        menu = QMenu(self)
        for state in (self.Available, self.Away, self.Busy, self.Invisible):
            action = menu.addAction(QIcon(state.icon), state.name)
            action.state = state
            action.note = None
        menu.addSeparator()
        menu.triggered.connect(self._SH_MenuTriggered)
        self.setMenu(menu)
        self.state = self.Invisible
        self.note = None

    def _get_history(self):
        return [(action.state.name, action.note)
                for action in self.menu().actions()[5:]]

    def _set_history(self, values):
        menu = self.menu()
        for action in menu.actions()[5:]:
            menu.removeAction(action)
        for state_name, note in values:
            try:
                state = getattr(self, state_name)
            except AttributeError:
                continue
            action = menu.addAction(QIcon(state.icon), note)
            action.state = state
            action.note = note

    history = property(_get_history, _set_history)
    del _get_history, _set_history

    def _SH_MenuTriggered(self, action):
        if hasattr(action, 'state'):
            self.setState(action.state, action.note)

    def mousePressEvent_no(self, event):
        if event.button() == Qt.LeftButton and self.popupMode(
        ) == QToolButton.MenuButtonPopup:
            option = QStyleOptionToolButton()
            self.initStyleOption(option)
            position = self.style().subControlRect(QStyle.CC_ToolButton,
                                                   option,
                                                   QStyle.SC_ToolButtonMenu,
                                                   self).center()
            event = event.__class__(event.type(), position,
                                    self.mapToGlobal(position), event.button(),
                                    event.buttons(), event.modifiers())
        return super(AccountState, self).mousePressEvent(event)

    def setState(self, state, note=None):
        if state == self.state and note == self.note:
            return
        self.state = state
        self.note = note
        palette = self.palette()
        palette.setColor(QPalette.Button, QColor(state.color))
        self.setPalette(palette)
        if note and not state.internal:
            menu = self.menu()
            actions = menu.actions()[5:]
            try:
                action = next(action for action in actions
                              if action.state is state and action.note == note)
            except StopIteration:
                action = QAction(QIcon(state.icon), note, menu)
                if len(actions) == 0:
                    menu.addAction(action)
                else:
                    if len(actions) >= self.history_size:
                        menu.removeAction(actions[-1])
                    menu.insertAction(actions[0], action)
                action.state = state
                action.note = note
            else:
                if action is not actions[0]:
                    menu.removeAction(action)
                    menu.insertAction(actions[0], action)
        self.stateChanged.emit()
Exemplo n.º 51
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.idle_status_index = 0

        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()

        self.setWindowTitle('Blink')
        self.setWindowIconText('Blink')
        self.set_user_icon(Resources.get("icons/default-avatar.png")) # ":/resources/icons/default-avatar.png"

        self.active_sessions_label.hide()
        self.enable_call_buttons(False)
        self.conference_button.setEnabled(False)
        self.hangup_all_button.setEnabled(False)
        self.sip_server_settings_action.setEnabled(False)
        self.search_for_people_action.setEnabled(False)
        self.history_on_server_action.setEnabled(False)
        self.buy_pstn_access_action.setEnabled(False)
        self.main_view.setCurrentWidget(self.contacts_panel)
        self.contacts_view.setCurrentWidget(self.contact_list_panel)
        self.search_view.setCurrentWidget(self.search_list_panel)

        # Accounts
        self.account_model = AccountModel(self)
        self.enabled_account_model = ActiveAccountModel(self.account_model, self)
        self.server_tools_account_model = ServerToolsAccountModel(self.account_model, self)
        self.identity.setModel(self.enabled_account_model)

        # Contacts
        self.contact_model = ContactModel(self)
        self.contact_search_model = ContactSearchModel(self.contact_model, self)
        self.contact_list.setModel(self.contact_model)
        self.search_list.setModel(self.contact_search_model)

        # Sessions
        self.session_model = SessionModel(self)
        self.session_list.setModel(self.session_model)

        self.session_list.selectionModel().selectionChanged.connect(self._SH_SessionListSelectionChanged)

        # Windows, dialogs and panels
        self.about_panel = AboutPanel(self)
        self.contact_editor_dialog = ContactEditorDialog(self.contact_model, self)
        self.google_contacts_dialog = GoogleContactsDialog(self)
        self.preferences_window = PreferencesWindow(self.account_model, None)
        self.server_tools_window = ServerToolsWindow(self.server_tools_account_model, None)

        # Signals
        self.add_contact_button.clicked.connect(self._SH_AddContactButtonClicked)
        self.add_search_contact_button.clicked.connect(self._SH_AddContactButtonClicked)
        self.audio_call_button.clicked.connect(self._SH_AudioCallButtonClicked)
        self.back_to_contacts_button.clicked.connect(self.search_box.clear) # this can be set in designer -Dan
        self.conference_button.makeConference.connect(self._SH_MakeConference)
        self.conference_button.breakConference.connect(self._SH_BreakConference)

        self.contact_list.doubleClicked.connect(self._SH_ContactDoubleClicked) # activated is emitted on single click
        self.contact_list.selectionModel().selectionChanged.connect(self._SH_ContactListSelectionChanged)
        self.contact_model.itemsAdded.connect(self._SH_ContactModelAddedItems)
        self.contact_model.itemsRemoved.connect(self._SH_ContactModelRemovedItems)

        self.display_name.editingFinished.connect(self._SH_DisplayNameEditingFinished)
        self.hangup_all_button.clicked.connect(self._SH_HangupAllButtonClicked)

        self.identity.activated[int].connect(self._SH_IdentityChanged)
        self.identity.currentIndexChanged[int].connect(self._SH_IdentityCurrentIndexChanged)

        self.mute_button.clicked.connect(self._SH_MuteButtonClicked)

        self.search_box.textChanged.connect(self._SH_SearchBoxTextChanged)
        self.search_box.textChanged.connect(self.contact_search_model.setFilterFixedString)
        self.search_box.returnPressed.connect(self._SH_SearchBoxReturnPressed)
        self.search_box.shortcut.activated.connect(self.search_box.setFocus)

        self.search_list.selectionModel().selectionChanged.connect(self._SH_SearchListSelectionChanged)
        self.search_list.doubleClicked.connect(self._SH_ContactDoubleClicked) # activated is emitted on single click

        self.server_tools_account_model.rowsInserted.connect(self._SH_ServerToolsAccountModelChanged)
        self.server_tools_account_model.rowsRemoved.connect(self._SH_ServerToolsAccountModelChanged)

        self.session_model.sessionAdded.connect(self._SH_SessionModelAddedSession)
        self.session_model.structureChanged.connect(self._SH_SessionModelChangedStructure)

        self.silent_button.clicked.connect(self._SH_SilentButtonClicked)
        self.status.activated[int].connect(self._SH_StatusChanged)
        self.switch_view_button.viewChanged.connect(self._SH_SwitchViewButtonChangedView)

        # Blink menu actions
        self.about_action.triggered.connect(self.about_panel.show)
        self.donate_action.triggered.connect(partial(QDesktopServices.openUrl, QUrl(u'http://icanblink.com/payments.phtml')))
        self.add_account_action.triggered.connect(self.preferences_window.show_add_account_dialog)
        self.manage_accounts_action.triggered.connect(self.preferences_window.show_for_accounts)
        self.help_action.triggered.connect(partial(QDesktopServices.openUrl, QUrl(u'http://icanblink.com/help-qt.phtml')))
        self.preferences_action.triggered.connect(self.preferences_window.show)
        self.auto_accept_chat_action.triggered.connect(self._AH_AutoAcceptChatTriggered)
        self.auto_accept_files_action.triggered.connect(self._AH_AutoAcceptFilesTriggered)
        self.release_notes_action.triggered.connect(partial(QDesktopServices.openUrl, QUrl(u'http://icanblink.com/changelog-qt.phtml')))
        self.quit_action.triggered.connect(self.close)

        # Audio menu actions
        self.mute_action.triggered.connect(self._SH_MuteButtonClicked)
        self.silent_action.triggered.connect(self._SH_SilentButtonClicked)
        self.output_devices_group.triggered.connect(self._AH_AudioOutputDeviceChanged)
        self.input_devices_group.triggered.connect(self._AH_AudioInputDeviceChanged)
        self.alert_devices_group.triggered.connect(self._AH_AudioAlertDeviceChanged)

        # History menu actions
        self.redial_action.triggered.connect(self._AH_RedialActionTriggered)

        # Tools menu actions
        self.answering_machine_action.triggered.connect(self._AH_EnableAnsweringMachineTriggered)
        self.sip_server_settings_action.triggered.connect(self._AH_SIPServerSettings)
        self.search_for_people_action.triggered.connect(self._AH_SearchForPeople)
        self.history_on_server_action.triggered.connect(self._AH_HistoryOnServer)
        self.buy_pstn_access_action.triggered.connect(self._AH_PurchasePstnAccess)

        self.contact_model.load()
Exemplo n.º 52
0
 def __init__(self, parent=None, icon='icons/spinner.svg'):
     super(Spinner, self).__init__(parent)
     self._original_viewbox = QRectF()
     self.icon_crop = 0
     self.icon_size = None
     self.icon_file = Resources.get(icon)
Exemplo n.º 53
0
class TLSSettingsExtension(TLSSettings):
    ca_list = Setting(type=ApplicationDataPath,
                      default=ApplicationDataPath(Resources.get('tls/ca.crt')),
                      nillable=True)
Exemplo n.º 54
0
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtWidgets import QAction, QMenu

from application.notification import IObserver, NotificationCenter
from application.python import Null
from application.system import makedirs
from zope.interface import implementer

from blink.configuration.settings import BlinkSettings
from blink.resources import Resources
from blink.sessions import FileTransferDelegate, FileTransferModel
from blink.widgets.util import ContextMenuActions

__all__ = ['FileTransferWindow']

ui_class, base_class = uic.loadUiType(Resources.get('filetransfer_window.ui'))


@implementer(IObserver)
class FileTransferWindow(base_class, ui_class):
    def __init__(self, parent=None):
        super(FileTransferWindow, self).__init__(parent)
        with Resources.directory:
            self.setupUi(self)

        self.model = FileTransferModel(self)
        self.listview.setModel(self.model)
        self.listview.setItemDelegate(FileTransferDelegate(self.listview))
        self.listview.customContextMenuRequested.connect(
            self._SH_ContextMenuRequested)
Exemplo n.º 55
0
                self.transform.mapRect(QRect(x, y, w, h)).adjusted(
                    -1, -1, 1, 1).intersected(self.rect()))
        else:
            self.update(x, y, w, h)

    def _SH_PasswordRequested(self, with_username):
        dialog = ScreensharingDialog(self)
        if with_username:
            username, password = dialog.get_credentials()
        else:
            username, password = None, dialog.get_password()
        self.client.username = username
        self.client.password = password


ui_class, base_class = uic.loadUiType(Resources.get('screensharing_dialog.ui'))


class ScreensharingDialog(base_class, ui_class):
    def __init__(self, parent=None):
        super(ScreensharingDialog, self).__init__(parent)
        with Resources.directory:
            self.setupUi(self)
        self.setWindowModality(Qt.WindowModal)
        parent.installEventFilter(self)

    def eventFilter(self, watched, event):
        if watched is self.parent() and event.type() in (QEvent.Close,
                                                         QEvent.Hide):
            self.reject()
        return False
Exemplo n.º 56
0
from PyQt4 import uic
from PyQt4.QtCore import Qt, QUrl
from PyQt4.QtGui  import QAction, QDesktopServices, QMenu

from application.notification import IObserver, NotificationCenter
from application.python import Null
from application.system import makedirs
from zope.interface import implements

from blink.configuration.settings import BlinkSettings
from blink.resources import Resources
from blink.sessions import FileTransferDelegate, FileTransferModel
from blink.widgets.util import ContextMenuActions


ui_class, base_class = uic.loadUiType(Resources.get('filetransfer_window.ui'))

class FileTransferWindow(base_class, ui_class):
    implements(IObserver)

    def __init__(self, parent=None):
        super(FileTransferWindow, self).__init__(parent)
        with Resources.directory:
            self.setupUi(self)

        self.model = FileTransferModel(self)
        self.listview.setModel(self.model)
        self.listview.setItemDelegate(FileTransferDelegate(self.listview))
        self.listview.customContextMenuRequested.connect(self._SH_ContextMenuRequested)

        self.context_menu = QMenu(self.listview)
Exemplo n.º 57
0
from blink.aboutpanel import AboutPanel
from blink.accounts import AccountModel, ActiveAccountModel, ServerToolsAccountModel, ServerToolsWindow
from blink.contacts import Contact, ContactEditorDialog, ContactModel, ContactSearchModel, GoogleContactsDialog, URIUtils
from blink.filetransferwindow import FileTransferWindow
from blink.history import HistoryManager
from blink.preferences import PreferencesWindow
from blink.sessions import ConferenceDialog, SessionManager, AudioSessionModel, StreamDescription
from blink.configuration.datatypes import IconDescriptor, FileURL, InvalidToken, PresenceState
from blink.configuration.settings import BlinkSettings
from blink.presence import PendingWatcherDialog
from blink.resources import ApplicationData, IconManager, Resources
from blink.util import run_in_gui_thread
from blink.widgets.buttons import AccountState, SwitchViewButton


ui_class, base_class = uic.loadUiType(Resources.get('blink.ui'))

class MainWindow(base_class, ui_class):
    implements(IObserver)

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.saved_account_state = None

        notification_center = NotificationCenter()
        notification_center.add_observer(self, name='SIPApplicationWillStart')
        notification_center.add_observer(self, name='SIPApplicationDidStart')
        notification_center.add_observer(self, name='SIPAccountGotMessageSummary')
        notification_center.add_observer(self, name='SIPAccountGotPendingWatcher')
        notification_center.add_observer(self, name='BlinkSessionNewOutgoing')
        notification_center.add_observer(self, name='BlinkSessionDidReinitializeForOutgoing')
Exemplo n.º 58
0
 def __init__(self, parent=None, icon='icons/spinner.svg'):
     super(Spinner, self).__init__(parent)
     self._original_viewbox = QRectF()
     self.icon_crop = 0
     self.icon_size = None
     self.icon_file = Resources.get(icon)