def initWithFrame_(self, frame):
        self = NSView.initWithFrame_(self, frame)
        if self:
            self.items = []

            self.leftButton = NSButton.alloc().initWithFrame_(
                NSMakeRect(0, 0, 20, 20))
            self.leftButton.setTarget_(self)
            self.leftButton.setAction_("scrollLeft:")
            self.leftButton.setImage_(
                NSImage.imageNamed_("NSLeftFacingTriangleTemplate"))
            self.leftButton.setHidden_(True)
            self.leftButton.cell().setBezelStyle_(NSShadowlessSquareBezelStyle)
            self.addSubview_(self.leftButton)

            self.rightButton = NSButton.alloc().initWithFrame_(
                NSMakeRect(0, 0, 20, 20))
            self.rightButton.setTarget_(self)
            self.rightButton.setAction_("scrollRight:")
            self.rightButton.setImage_(
                NSImage.imageNamed_("NSRightFacingTriangleTemplate"))
            self.rightButton.setHidden_(True)
            self.rightButton.cell().setBezelStyle_(
                NSShadowlessSquareBezelStyle)
            self.addSubview_(self.rightButton)

        return self
 def awakeFromNib(self):
     self.fullscreenButton.setImage_(NSImage.imageNamed_("restore" if self.videoWindowController.full_screen else "fullscreen"))
     self.updateMuteButton()
     audio_stream = self.sessionController.streamHandlerOfType("audio")
     if audio_stream:
         if audio_stream.status == STREAM_CONNECTED:
             if audio_stream.holdByLocal or audio_stream.holdByRemote:
                 self.holdButton.setImage_(NSImage.imageNamed_("paused-red"))
             else:
                 self.holdButton.setImage_(NSImage.imageNamed_("pause-white"))
         else:
             self.holdButton.setImage_(NSImage.imageNamed_("pause-white"))
     else:
         self.holdButton.setImage_(NSImage.imageNamed_("pause-white"))
    def userClickedToolbarItem_(self, sender):
        if sender.itemIdentifier() == 'smileys':
            self.chatViewController.expandSmileys = not self.chatViewController.expandSmileys
            sender.setImage_(NSImage.imageNamed_("smiley_on" if self.chatViewController.expandSmileys else "smiley_off"))
            self.chatViewController.toggleSmileys(self.chatViewController.expandSmileys)

            row = self.contactTable.selectedRow()
            if row and row > 1 and self.contacts[row].presence_contact is not None:
                self.contacts[row].presence_contact.contact.disable_smileys = not self.contacts[row].presence_contact.contact.disable_smileys
                self.contacts[row].presence_contact.contact.save()

        elif sender.itemIdentifier() == 'delete':
            if self.selectedTableView == self.contactTable:
                try:
                    row = self.contactTable.selectedRow()
                    self.showDeleteConfirmationDialog(row)
                except IndexError:
                    pass

            elif self.selectedTableView == self.indexTable:
                try:
                    row = self.indexTable.selectedRow()
                    local_uri = self.dayly_entries[row].objectForKey_("local_uri")
                    remote_uri = self.dayly_entries[row].objectForKey_("remote_uri")
                    remote_uri_sql = self.dayly_entries[row].objectForKey_("remote_uri_sql")
                    date = self.dayly_entries[row].objectForKey_("date")
                    media_type = self.dayly_entries[row].objectForKey_("type")

                    label = NSLocalizedString("Please confirm the deletion of %s history entries", "Label") % media_type + NSLocalizedString(" from %s", "SIP Address label") % remote_uri + NSLocalizedString(" on %s. ", "Date label") % date + NSLocalizedString("This operation cannot be undone. ", "Label")
                    ret = NSRunAlertPanel(NSLocalizedString("Purge History Entries", "Window title"), label, NSLocalizedString("Confirm", "Button title"), NSLocalizedString("Cancel", "Button title"), None)
                    if ret == NSAlertDefaultReturn:
                        self.delete_messages(local_uri=local_uri, remote_uri=remote_uri_sql, media_type=media_type, date=date)
                except IndexError:
                    pass
 def tableViewSelectionDidChange_(self, notification):
     if self.chat_history:
         if notification.object() == self.contactTable:
             row = self.contactTable.selectedRow()
             if row < 0:
                 return
             elif row == 0:
                 self.search_local = None
                 self.search_uris = None
                 self.searchContactBox.setStringValue_('')
                 self.refreshContacts()
             elif row == 1:
                 self.search_local = 'bonjour.local'
                 self.search_uris = None
             elif row > 1:
                 self.search_local = None
                 if self.contacts[row].presence_contact is not None:
                     self.search_uris = list(str(contact_uri.uri) for contact_uri in self.contacts[row].presence_contact.uris)
                     self.chatViewController.expandSmileys = not self.contacts[row].presence_contact.contact.disable_smileys
                     self.chatViewController.toggleSmileys(self.chatViewController.expandSmileys)
                     try:
                         item = next((item for item in self.toolbar.visibleItems() if item.itemIdentifier() == 'smileys'))
                     except StopIteration:
                         pass
                     else:
                         item.setImage_(NSImage.imageNamed_("smiley_on" if self.chatViewController.expandSmileys else "smiley_off"))
                 else:
                     self.search_uris = (self.contacts[row].uri,)
             self.refreshDailyEntries()
             self.refreshMessages()
         else:
             row = self.indexTable.selectedRow()
             if row >= 0:
                 self.refreshMessages(remote_uri=(self.dayly_entries[row].objectForKey_("remote_uri_sql"),), local_uri=self.dayly_entries[row].objectForKey_("local_uri"), date=self.dayly_entries[row].objectForKey_("date"), media_type=self.dayly_entries[row].objectForKey_("type"))
 def tableViewSelectionDidChange_(self, notification):
     if self.chat_history:
         if notification.object() == self.contactTable:
             row = self.contactTable.selectedRow()
             if row < 0:
                 return
             elif row == 0:
                 self.search_local = None
                 self.search_uris = None
                 self.searchContactBox.setStringValue_('')
                 self.refreshContacts()
             elif row == 1:
                 self.search_local = 'bonjour'
                 self.search_uris = None
             elif row > 1:
                 self.search_local = None
                 if self.contacts[row].presence_contact is not None:
                     self.search_uris = list(unicode(contact_uri.uri) for contact_uri in self.contacts[row].presence_contact.uris)
                     self.chatViewController.expandSmileys = not self.contacts[row].presence_contact.contact.disable_smileys
                     self.chatViewController.toggleSmileys(self.chatViewController.expandSmileys)
                     try:
                         item = (item for item in self.toolbar.visibleItems() if item.itemIdentifier() == 'smileys').next()
                     except StopIteration:
                         pass
                     else:
                         item.setImage_(NSImage.imageNamed_("smiley_on" if self.chatViewController.expandSmileys else "smiley_off"))
                 else:
                     self.search_uris = (self.contacts[row].uri,)
             self.refreshDailyEntries()
             self.refreshMessages()
         else:
             row = self.indexTable.selectedRow()
             if row >= 0:
                 self.refreshMessages(remote_uri=(self.dayly_entries[row].objectForKey_("remote_uri_sql"),), local_uri=self.dayly_entries[row].objectForKey_("local_uri"), date=self.dayly_entries[row].objectForKey_("date"), media_type=self.dayly_entries[row].objectForKey_("type"))
    def userClickedToolbarItem_(self, sender):
        if sender.itemIdentifier() == 'smileys':
            self.chatViewController.expandSmileys = not self.chatViewController.expandSmileys
            sender.setImage_(NSImage.imageNamed_("smiley_on" if self.chatViewController.expandSmileys else "smiley_off"))
            self.chatViewController.toggleSmileys(self.chatViewController.expandSmileys)

            row = self.contactTable.selectedRow()
            if row and row > 1 and self.contacts[row].presence_contact is not None:
                self.contacts[row].presence_contact.contact.disable_smileys = not self.contacts[row].presence_contact.contact.disable_smileys
                self.contacts[row].presence_contact.contact.save()

        elif sender.itemIdentifier() == 'delete':
            if self.selectedTableView == self.contactTable:
                try:
                    row = self.contactTable.selectedRow()
                    self.showDeleteConfirmationDialog(row)
                except IndexError:
                    pass

            elif self.selectedTableView == self.indexTable:
                try:
                    row = self.indexTable.selectedRow()
                    local_uri = self.dayly_entries[row].objectForKey_("local_uri")
                    remote_uri = self.dayly_entries[row].objectForKey_("remote_uri")
                    remote_uri_sql = self.dayly_entries[row].objectForKey_("remote_uri_sql")
                    date = self.dayly_entries[row].objectForKey_("date")
                    media_type = self.dayly_entries[row].objectForKey_("type")

                    label = NSLocalizedString("Please confirm the deletion of %s history entries" % media_type, "Text label") + NSLocalizedString(" from %s" % remote_uri, "SIP Address label") + NSLocalizedString(" on %s. " % date, "Date label") + NSLocalizedString("This operation cannot be undone. ", "Text label")
                    ret = NSRunAlertPanel(NSLocalizedString("Purge History Entries", "Window title"), label, NSLocalizedString("Confirm", "Button title"), NSLocalizedString("Cancel", "Button title"), None)
                    if ret == NSAlertDefaultReturn:
                        self.delete_messages(local_uri=local_uri, remote_uri=remote_uri_sql, media_type=media_type, date=date)
                except IndexError:
                    pass
    def updateIcon(self, icon):
        image = NSImage.alloc().initWithSize_(NSMakeSize(48,48))
        image.lockFocus()
        size = icon.size()
        icon.drawAtPoint_fromRect_operation_fraction_(NSMakePoint((48-size.width)/2, (48-size.height)/2),
                NSMakeRect(0, 0, size.width, size.height), NSCompositeSourceOver, 1)

        # overlay file transfer direction icon
        if type(self.transfer) == OutgoingPushFileTransferHandler or (self.oldTransferInfo and self.oldTransferInfo.direction == "outgoing"):
            icon = NSImage.imageNamed_("outgoing_file")
        else:
            icon = NSImage.imageNamed_("incoming_file")
        icon.drawAtPoint_fromRect_operation_fraction_(NSMakePoint(2, 4), NSMakeRect(0, 0, size.width, size.height), NSCompositeSourceOver, 1)
        image.unlockFocus()

        self.icon.setImage_(image)
Exemple #8
0
    def render_pidf(self):
        if not self.contact:
            return
        has_locations = False
        status_label = ''
        if self.contact.presence_state['devices']:
            has_locations = any(device['location'] for device in list(self.contact.presence_state['devices'].values()) if device['location'] is not None)
            count = len(self.contact.presence_state['devices'])
            if count == 1:
                status_label = NSLocalizedString("One device available", "Label")
            elif count > 1:
                status_label = NSLocalizedString("%d devices available" % count, "Label")

        splitViewFrame = self.splitView.frame()
        mapViewFrame = self.mapViewSplitView.frame()
        pidfViewFrame = self.pidfView.frame()

        if has_locations:
            if mapViewFrame.size.height == 0:
                mapViewFrame.size.height = SPLITTER_HEIGHT
                self.mapViewSplitView.setFrame_(mapViewFrame)
                pidfViewFrame.size.height -= SPLITTER_HEIGHT
                self.pidfView.setFrame_(pidfViewFrame)
            self.mapView.setContact(self.contact)
            nr_countries = len(self.mapView.selectedCountries)
            if nr_countries == 1:
                status_label += NSLocalizedString(" in one country", "Label")
            elif nr_countries > 1:
                status_label +=  NSLocalizedString(" in %d countries" % nr_countries, "Label")
        else:
            mapViewFrame.size.height = 0
            self.mapViewSplitView.setFrame_(mapViewFrame)
            pidfViewFrame.size.height = splitViewFrame.size.height
            self.pidfView.setFrame_(pidfViewFrame)

        self.statusLabel.setStringValue_(status_label)

        text = ''
        for pidf in self.contact.pidfs:
            text += self.build_pidf_text(pidf) + '\n\n'

        if self.contact.presence_state['pending_authorizations']:
            text += "Pending authorizations:\n"

        pending_authorizations = self.contact.presence_state['pending_authorizations']
        for key in list(pending_authorizations.keys()):
            text += "    Subscription to %s from account %s\n" % (sip_prefix_pattern.sub('', key), pending_authorizations[key])

        self.presenceText.textStorage().deleteCharactersInRange_(NSMakeRange(0, self.presenceText.textStorage().length()))
        astring = NSAttributedString.alloc().initWithString_(text)
        self.presenceText.textStorage().appendAttributedString_(astring)

        image = presence_status_for_contact(self.contact)
        if image:
            icon = NSImage.imageNamed_(image)
            icon.setScalesWhenResized_(True)
            icon.setSize_(NSMakeSize(12,12))
            self.presence_icon.setImage_(icon)
    def render_pidf(self):
        if not self.contact:
            return
        has_locations = False
        status_label = ''
        if self.contact.presence_state['devices']:
            has_locations = any(device['location'] for device in self.contact.presence_state['devices'].values() if device['location'] is not None)
            count = len(self.contact.presence_state['devices'])
            if count == 1:
                status_label = 'One device available'
            elif count > 1:
                status_label = '%d devices available' % count

        splitViewFrame = self.splitView.frame()
        mapViewFrame = self.mapViewSplitView.frame()
        pidfViewFrame = self.pidfView.frame()

        if has_locations:
            if mapViewFrame.size.height == 0:
                mapViewFrame.size.height = SPLITTER_HEIGHT
                self.mapViewSplitView.setFrame_(mapViewFrame)
                pidfViewFrame.size.height -= SPLITTER_HEIGHT
                self.pidfView.setFrame_(pidfViewFrame)
            self.mapView.setContact(self.contact)
            nr_countries = len(self.mapView.selectedCountries)
            if nr_countries == 1:
                status_label += ' in one country'
            elif nr_countries > 1:
                status_label += ' in %d countries' % nr_countries
        else:
            mapViewFrame.size.height = 0
            self.mapViewSplitView.setFrame_(mapViewFrame)
            pidfViewFrame.size.height = splitViewFrame.size.height
            self.pidfView.setFrame_(pidfViewFrame)

        self.statusLabel.setStringValue_(status_label)

        text = ''
        for pidf in self.contact.pidfs:
            text += self.build_pidf_text(pidf) + '\n\n'

        if self.contact.presence_state['pending_authorizations']:
            text += "Pending authorizations:\n"

        pending_authorizations = self.contact.presence_state['pending_authorizations']
        for key in pending_authorizations.keys():
            text += "    Subscription to %s from account %s\n" % (sip_prefix_pattern.sub('', key), pending_authorizations[key])

        self.presenceText.textStorage().deleteCharactersInRange_(NSMakeRange(0, self.presenceText.textStorage().length()))
        astring = NSAttributedString.alloc().initWithString_(text)
        self.presenceText.textStorage().appendAttributedString_(astring)

        image = presence_status_for_contact(self.contact)
        if image:
            icon = NSImage.imageNamed_(image)
            icon.setScalesWhenResized_(True)
            icon.setSize_(NSMakeSize(12,12))
            self.presence_icon.setImage_(icon)
    def updateEncryptionWidgets(self, selectedSession=None):
        if selectedSession is None:
            selectedSession = self.selectedSessionController()

        if selectedSession and selectedSession.started:
            if selectedSession.encryption.active:
                if selectedSession.encryption.verified:
                    self.encryptionIconMenuItem.setImage_(
                        NSImage.imageNamed_("locked-green"))
                else:
                    self.encryptionIconMenuItem.setImage_(
                        NSImage.imageNamed_("locked-red"))
            else:
                self.encryptionIconMenuItem.setImage_(
                    NSImage.imageNamed_("unlocked-darkgray"))
        else:
            self.encryptionIconMenuItem.setImage_(
                NSImage.imageNamed_("unlocked-darkgray"))
    def orderFrontAboutPanel_(self, sender):
        if not self.aboutPanel:
            NSBundle.loadNibNamed_owner_("About", self)
            self.aboutVersion.setStringValue_(self.about_version)
            self.aboutSlogan.setStringValue_(self.about_slogan)
            self.aboutIcon.setImage_(NSImage.imageNamed_(self.about_image))
            self.aboutCopyright.setStringValue_(self.about_copyright)

        self.aboutPanel.makeKeyAndOrderFront_(None)
 def userClickedToolbarButton_(self, sender):
     if sender.tag() == 100:
         self.fitWindowButton.setState_(NSOffState if self.fitWindowButton.
                                        state() == NSOnState else NSOnState)
         self.fitWindowButton.setImage_(
             NSImage.imageNamed_(
                 'shrinktofit-pressed'
                 if not self.screensharing_fit_window else 'shrinktofit'))
         self.screensharing_fit_window = False if self.screensharing_fit_window else True
         self.startLoading()
 def toolbarButtonClicked_(self, sender):
     if sender.itemIdentifier() == 'smileys':
         chatViewController = self.selectedSessionController().chatViewController
         chatViewController.expandSmileys = not chatViewController.expandSmileys
         sender.setImage_(NSImage.imageNamed_("smiley_on" if chatViewController.expandSmileys else "smiley_off"))
         chatViewController.toggleSmileys(chatViewController.expandSmileys)
     elif sender.itemIdentifier() == 'history' and NSApp.delegate().applicationName != 'Blink Lite':
         contactWindow = self._owner._owner
         contactWindow.showHistoryViewer_(None)
         session = self.selectedSessionController()
         contactWindow.historyViewer.filterByURIs((format_identity_to_string(session.target_uri),))
    def makeDragImage(self):
        if self.delegate is None:
            return

        image = NSImage.alloc().initWithSize_(self.frame().size)
        image.lockFocus()

        frame = self.frame()
        frame.origin = NSZeroPoint
        rect = NSInsetRect(frame, 1.5, 1.5)

        if self.conferencing and not self.draggedOut:
            NSColor.selectedControlColor().colorWithAlphaComponent_(0.7).set()
        else:
            NSColor.whiteColor().colorWithAlphaComponent_(0.7).set()
        path = NSBezierPath.bezierPathWithRoundedRect_xRadius_yRadius_(rect, 5.0, 5.0)
        path.fill()

        if self.selected:
            path.setLineWidth_(3)
            NSColor.grayColor().set()
        else:
            path.setLineWidth_(1)
            NSColor.grayColor().set()
        path.stroke()

        NSColor.blackColor().set()
        point = NSMakePoint(8, NSMaxY(frame)-20)
        uri = format_identity_to_string(self.delegate.sessionController.remotePartyObject, check_contact=False, format='compact')
        NSString.stringWithString_(uri).drawAtPoint_withAttributes_(point,
              NSDictionary.dictionaryWithObjectsAndKeys_(NSFont.boldSystemFontOfSize_(12), NSFontAttributeName))
        point = NSMakePoint(8, 6)
        if self.conferencing:
            NSString.stringWithString_(NSLocalizedString("Drop outside to remove from conference", "Audio session label")).drawAtPoint_withAttributes_(point,
                  NSDictionary.dictionaryWithObjectsAndKeys_(NSFont.systemFontOfSize_(10), NSFontAttributeName))
        else:
            audio_sessions = [sess.hasStreamOfType("audio") for sess in NSApp.delegate().contactsWindowController.sessionControllersManager.sessionControllers]
            if self.delegate.transferEnabled:
                text = NSLocalizedString("Drop this over a session or contact", "Audio session label") if len(audio_sessions) > 1 else NSLocalizedString("Drop this over a contact to transfer", "Audio session label")
            else:
                text = NSLocalizedString("Drop this over a session to conference", "Audio session label")
            NSString.stringWithString_(text).drawAtPoint_withAttributes_(point,
                  NSDictionary.dictionaryWithObjectsAndKeys_(NSFont.systemFontOfSize_(10), NSFontAttributeName))

        icon = NSImage.imageNamed_("NSEveryone")
        rect = frame
        s = icon.size()
        p = NSMakePoint(NSWidth(rect) - s.width - 8, rect.size.height - s.height - 8)
        r = NSMakeRect(0, 0, s.width, s.height)
        icon.drawAtPoint_fromRect_operation_fraction_(p, r, NSCompositeSourceOver, 0.5)

        image.unlockFocus()
        return image
 def show(self, item):
     if not self.items:
         self.statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(30)
         self.menu = NSMenu.alloc().init()
         image = NSImage.imageNamed_("display").copy()
         image.setSize_(NSMakeSize(24, 24))
         self.statusItem.setImage_(image)
         self.statusItem.setMenu_(self.menu)
     self.items.append(item)
     mitem = self.menu.addItemWithTitle_action_keyEquivalent_("%s - Waiting" % item.sessionController.getTitle(),  "activateItem:", "")
     mitem.setTag_(item.sessionController.identifier)
     mitem.setTarget_(self)
    def initWithFrame_(self, frame):
        self = NSView.initWithFrame_(self, frame)
        if self:
            self.items = []

            self.leftButton = NSButton.alloc().initWithFrame_(NSMakeRect(0, 0, 20, 20))
            self.leftButton.setTarget_(self)
            self.leftButton.setAction_("scrollLeft:")
            self.leftButton.setImage_(NSImage.imageNamed_("NSLeftFacingTriangleTemplate"))
            self.leftButton.setHidden_(True)
            self.leftButton.cell().setBezelStyle_(NSShadowlessSquareBezelStyle)
            self.addSubview_(self.leftButton)

            self.rightButton = NSButton.alloc().initWithFrame_(NSMakeRect(0, 0, 20, 20))
            self.rightButton.setTarget_(self)
            self.rightButton.setAction_("scrollRight:")
            self.rightButton.setImage_(NSImage.imageNamed_("NSRightFacingTriangleTemplate"))
            self.rightButton.setHidden_(True)
            self.rightButton.cell().setBezelStyle_(NSShadowlessSquareBezelStyle)
            self.addSubview_(self.rightButton)

        return self
    def updateIcon(self, icon):
        image = NSImage.alloc().initWithSize_(NSMakeSize(48, 48))
        image.lockFocus()
        size = icon.size()
        icon.drawAtPoint_fromRect_operation_fraction_(
            NSMakePoint((48 - size.width) / 2, (48 - size.height) / 2),
            NSMakeRect(0, 0, size.width, size.height), NSCompositeSourceOver,
            1)

        # overlay file transfer direction icon
        if type(self.transfer) == OutgoingPushFileTransferHandler or (
                self.oldTransferInfo
                and self.oldTransferInfo.direction == "outgoing"):
            icon = NSImage.imageNamed_("outgoing_file")
        else:
            icon = NSImage.imageNamed_("incoming_file")
        icon.drawAtPoint_fromRect_operation_fraction_(
            NSMakePoint(2, 4), NSMakeRect(0, 0, size.width, size.height),
            NSCompositeSourceOver, 1)
        image.unlockFocus()

        self.icon.setImage_(image)
Exemple #18
0
 def show(self, item):
     if not self.items:
         #self.statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(30)
         self.statusItem = Null
         self.menu = NSMenu.alloc().init()
         image = NSImage.imageNamed_("display").copy()
         image.setSize_(NSMakeSize(24, 24))
         self.statusItem.setImage_(image)
         self.statusItem.setMenu_(self.menu)
     self.items.append(item)
     mitem = self.menu.addItemWithTitle_action_keyEquivalent_(
         NSLocalizedString("%s - Waiting", "Menu item") %
         item.sessionController.titleLong, "activateItem:", "")
     mitem.setTag_(item.sessionController.identifier)
     mitem.setTarget_(self)
 def updateDockTile(self):
     if self.missedCalls > 0 or self.missedChats > 0:
         icon = NSImage.imageNamed_("Blink")
         image = NSImageView.alloc().initWithFrame_(NSMakeRect(0, 0, 32, 32))
         image.setImage_(icon)
         if self.missedCalls > 0 and self.missedChats > 0:
             NSApp.dockTile().setBadgeLabel_("%i / %i" % (self.missedCalls, self.missedChats))
         else:
             NSApp.dockTile().setBadgeLabel_("%i" % (self.missedCalls + self.missedChats))
         NSApp.dockTile().setContentView_(image)
     else:
         NSApp.dockTile().setBadgeLabel_("")
         NSApp.dockTile().setContentView_(None)
         icon = None
     NSApp.setApplicationIconImage_(icon)
     NSApp.dockTile().display()
 def showAboutPlugin_(self, sender):
     icon = None
     info = objc.currentBundle().infoDictionary()
     if 'CFBundleIconFile' in info:
         icon_file = info['CFBundleIconFile']
         icon_path = objc.currentBundle().pathForImageResource_(icon_file)
         if icon_path is not None:
             icon = NSImage.alloc().initWithContentsOfFile_(icon_path)
     if icon is None:
         icon = NSImage.imageNamed_('NSApplicationIcon')
     options = {'Credits': NSAttributedString.alloc().initWithString_('ÇFULLUSERNAMEÈ'),
                'ApplicationName': self.name(),
                'ApplicationIcon': icon,
                'ApplicationVersion': info['CFBundleShortVersionString'],
                'Version': 'Coda %s' % NSBundle.mainBundle().infoDictionary()['CFBundleShortVersionString']}
     NSApp.orderFrontStandardAboutPanelWithOptions_(options)
 def updateDockTile(self):
     if self.missedCalls > 0 or self.missedChats > 0:
         icon = NSImage.imageNamed_("Blink")
         image = NSImageView.alloc().initWithFrame_(NSMakeRect(0, 0, 32, 32))
         image.setImage_(icon)
         if self.missedCalls > 0 and self.missedChats > 0:
             NSApp.dockTile().setBadgeLabel_("%i / %i" % (self.missedCalls, self.missedChats))
         else:
             NSApp.dockTile().setBadgeLabel_("%i" % (self.missedCalls + self.missedChats))
         NSApp.dockTile().setContentView_(image)
     else:
         NSApp.dockTile().setBadgeLabel_("")
         NSApp.dockTile().setContentView_(None)
         icon = None
     NSApp.setApplicationIconImage_(icon)
     NSApp.dockTile().display()
Exemple #22
0
 def toolbarButtonClicked_(self, sender):
     session = self.selectedSessionController()
     contactWindow = self._owner._owner
     if sender.itemIdentifier() == 'audio':
         contactWindow.startSessionWithTarget(
             format_identity_to_string(session.target_uri))
     elif sender.itemIdentifier() == 'video':
         contactWindow.startSessionWithTarget(format_identity_to_string(
             session.target_uri),
                                              media_type="video")
     elif sender.itemIdentifier() == 'smileys':
         chatViewController = self.selectedSessionController(
         ).chatViewController
         chatViewController.expandSmileys = not chatViewController.expandSmileys
         sender.setImage_(
             NSImage.imageNamed_("smiley_on" if chatViewController.
                                 expandSmileys else "smiley_off"))
         chatViewController.toggleSmileys(chatViewController.expandSmileys)
     elif sender.itemIdentifier() == 'history' and NSApp.delegate(
     ).history_enabled:
         contactWindow.showHistoryViewer_(None)
         contactWindow.historyViewer.filterByURIs(
             (format_identity_to_string(session.target_uri), ))
    def __init__(self):
        if self:
            BlinkLogger().log_debug('Starting History Viewer')
            NSBundle.loadNibNamed_owner_("HistoryViewer", self)

            self.all_contacts = BlinkHistoryViewerContact('Any Address', name=u'All Contacts')
            self.bonjour_contact = BlinkHistoryViewerContact('bonjour', name=u'Bonjour Neighbours', icon=NSImage.imageNamed_("NSBonjour"))

            self.notification_center = NotificationCenter()
            self.notification_center.add_observer(self, name='ChatViewControllerDidDisplayMessage')
            self.notification_center.add_observer(self, name='AudioCallLoggedToHistory')
            self.notification_center.add_observer(self, name='BlinkContactsHaveChanged')
            self.notification_center.add_observer(self, name='BlinkTableViewSelectionChaged')
            self.notification_center.add_observer(self, name='BlinkConferenceContactPresenceHasChanged')
            self.notification_center.add_observer(self, name='BlinkShouldTerminate')

            self.searchText.cell().setSendsSearchStringImmediately_(True)
            self.searchText.cell().setPlaceholderString_(NSLocalizedString("Type text and press Enter", "Placeholder text"))

            self.chatViewController.setContentFile_(NSBundle.mainBundle().pathForResource_ofType_("ChatView", "html"))
            self.chatViewController.setHandleScrolling_(False)
            self.entriesView.setShouldCloseWithWindow_(False)

            for c in ('remote_uri', 'local_uri', 'date', 'type'):
                col = self.indexTable.tableColumnWithIdentifier_(c)
                descriptor = NSSortDescriptor.alloc().initWithKey_ascending_(c, True)
                col.setSortDescriptorPrototype_(descriptor)

            self.chat_history = ChatHistory()
            self.session_history = SessionHistory()
            self.setPeriod(1)

            self.selectedTableView = self.contactTable
    def makeDragImage(self):
        if self.delegate is None:
            return

        image = NSImage.alloc().initWithSize_(self.frame().size)
        image.lockFocus()

        frame = self.frame()
        frame.origin = NSZeroPoint
        rect = NSInsetRect(frame, 1.5, 1.5)

        if self.conferencing and not self.draggedOut:
            NSColor.selectedControlColor().colorWithAlphaComponent_(0.7).set()
        else:
            NSColor.whiteColor().colorWithAlphaComponent_(0.7).set()
        path = NSBezierPath.bezierPathWithRoundedRect_xRadius_yRadius_(
            rect, 5.0, 5.0)
        path.fill()

        if self.selected:
            path.setLineWidth_(3)
            NSColor.grayColor().set()
        else:
            path.setLineWidth_(1)
            NSColor.grayColor().set()
        path.stroke()

        NSColor.blackColor().set()
        point = NSMakePoint(8, NSMaxY(frame) - 20)
        uri = format_identity_to_string(
            self.delegate.sessionController.remoteIdentity,
            check_contact=False,
            format='compact')
        NSString.stringWithString_(uri).drawAtPoint_withAttributes_(
            point,
            NSDictionary.dictionaryWithObjectsAndKeys_(
                NSFont.boldSystemFontOfSize_(12), NSFontAttributeName))
        point = NSMakePoint(8, 6)
        if self.conferencing:
            NSString.stringWithString_(
                NSLocalizedString(
                    "Drop outside to remove from conference",
                    "Audio status label")).drawAtPoint_withAttributes_(
                        point,
                        NSDictionary.dictionaryWithObjectsAndKeys_(
                            NSFont.systemFontOfSize_(10), NSFontAttributeName))
        else:
            audio_sessions = [
                sess.hasStreamOfType("audio")
                for sess in NSApp.delegate().contactsWindowController.
                sessionControllersManager.sessionControllers
            ]
            if self.delegate.transferEnabled:
                text = NSLocalizedString(
                    "Drop this over a session or contact", "Audio status label"
                ) if len(audio_sessions) > 1 else NSLocalizedString(
                    "Drop this over a contact to transfer",
                    "Audio status label")
            else:
                text = NSLocalizedString(
                    "Drop this over a session to conference",
                    "Audio status label")
            NSString.stringWithString_(text).drawAtPoint_withAttributes_(
                point,
                NSDictionary.dictionaryWithObjectsAndKeys_(
                    NSFont.systemFontOfSize_(10), NSFontAttributeName))

        icon = NSImage.imageNamed_("NSEveryone")
        rect = frame
        s = icon.size()
        p = NSMakePoint(
            NSWidth(rect) - s.width - 8, rect.size.height - s.height - 8)
        r = NSMakeRect(0, 0, s.width, s.height)
        icon.drawAtPoint_fromRect_operation_fraction_(p, r,
                                                      NSCompositeSourceOver,
                                                      0.5)

        image.unlockFocus()
        return image
    def userClickedToolbarButton_(self, sender):
        self.log_debug('userClickedToolbarButton_ %s' % self)

        if not self.videoWindowController:
            return

        if self.videoWindowController.full_screen_in_progress:
            return

        self.stopFadeTimer()

        if sender.itemIdentifier() == 'hangup':
            self.stopIdleTimer()
            self.window().orderOut_(None)
            self.sessionController.end()
        elif sender.itemIdentifier() == 'fullscreen':
            self.window().orderOut_(None)
            self.videoWindowController.toggleFullScreen()
        elif sender.itemIdentifier() == 'aspect':
            self.videoWindowController.changeAspectRatio()
        elif sender.itemIdentifier() == 'pause':
            self.pauseButton.setImage_(NSImage.imageNamed_("video-paused" if not self.streamController.paused else "video"))
            self.streamController.togglePause()
            print self.streamController.paused
        elif sender.itemIdentifier() == 'chat':
            if self.videoWindowController.always_on_top:
                self.videoWindowController.toogleAlwaysOnTop()
            chat_stream = self.sessionController.streamHandlerOfType("chat")
            if chat_stream:
                if chat_stream.status in (STREAM_IDLE, STREAM_FAILED):
                    self.sessionController.startChatSession()
            else:
                self.sessionController.addChatToSession()

            if self.videoWindowController.full_screen:
                NSApp.delegate().contactsWindowController.showChatWindow_(None)
                self.videoWindowController.goToWindowMode(NSApp.delegate().contactsWindowController.chatWindowController.window())

        elif sender.itemIdentifier() == 'info':
            if self.sessionController.info_panel is not None:
                self.sessionController.info_panel.toggle()
        elif sender.itemIdentifier() == 'mirror':
            NSApp.delegate().contactsWindowController.toggleLocalVideoWindow_(sender)
        elif sender.itemIdentifier() == 'mute':
            SIPManager().mute(not SIPManager().is_muted())
            self.muteButton.setImage_(NSImage.imageNamed_("muted" if SIPManager().is_muted() else "mute-white"))
        elif sender.itemIdentifier() == 'contacts':
            if self.videoWindowController.full_screen:
                self.videoWindowController.toggleFullScreen()
            NSApp.delegate().contactsWindowController.focusSearchTextField()
        elif sender.itemIdentifier() == 'hold':
            if self.sessionController.hasStreamOfType("audio"):
                audio_stream = self.sessionController.streamHandlerOfType("audio")
                if audio_stream and audio_stream.status == STREAM_CONNECTED and not self.sessionController.inProposal:
                    if audio_stream.holdByLocal:
                        audio_stream.unhold()
                        audio_stream.view.setSelected_(True)
                        sender.setImage_(NSImage.imageNamed_("pause-white"))
                    else:
                        sender.setImage_(NSImage.imageNamed_("paused-red"))
                        audio_stream.hold()
 def updateMuteButton(self):
     self.muteButton.setImage_(NSImage.imageNamed_("muted" if SIPManager().is_muted() else "mute-white"))
 def _NH_BlinkVideoWindowFullScreenChanged(self, sender, data):
     if sender.full_screen:
         self.fullscreenButton.setImage_(NSImage.imageNamed_("restore"))
     else:
         self.fullscreenButton.setImage_(NSImage.imageNamed_("fullscreen"))
Exemple #28
0
    def updateVideo(self):
        if self.video_status.stringValue() and (
                self.sessionController is None or self.video_stream is None
                or self.video_stream.stream is None):
            self.resetVideo()
        elif (self.sessionController is not None
              and self.video_stream is not None
              and self.video_stream.stream is not None):
            self.updateVideoStatus()

            self.video_rx_speed_graph.setDataQueue_needsDisplay_(
                self.video_stream.rx_speed_history,
                True if self.window.isVisible() else False)
            self.video_tx_speed_graph.setDataQueue_needsDisplay_(
                self.video_stream.tx_speed_history,
                True if self.window.isVisible() else False)

            rtt = self.video_stream.statistics['rtt']
            if rtt > 1000:
                text = '%.1f s' % (float(rtt) / 1000.0)
            elif rtt > 100:
                text = '%d ms' % rtt
            elif rtt:
                text = '%d ms' % rtt
            else:
                text = ''

            self.video_rx_speed.setStringValue_('Rx %s/s' % format_size(
                self.video_stream.statistics['rx_bytes'], bits=True))
            self.video_tx_speed.setStringValue_('Tx %s/s' % format_size(
                self.video_stream.statistics['tx_bytes'], bits=True))

            if self.video_stream.stream.codec and self.video_stream.stream.sample_rate:
                codec = beautify_video_codec(self.video_stream.stream.codec)

                try:
                    settings = SIPSimpleSettings()
                    sample_rate = self.video_stream.stream.sample_rate / 1000
                    codec = codec + " @%d fps" % self.video_stream.statistics[
                        'fps']

                except TypeError:
                    pass

                self.video_codec.setStringValue_(codec)
                self.video_srtp_lock.setHidden_(
                    False if self.video_stream.encryption_active else True)
                if self.video_stream.encryption_active:
                    if self.video_stream.zrtp_active:
                        self.video_srtp_lock.setImage_(
                            NSImage.imageNamed_("locked-green") if self.
                            video_stream.zrtp_verified else NSImage.
                            imageNamed_("locked-red"))
                    else:
                        self.video_srtp_lock.setImage_(
                            NSImage.imageNamed_("srtp"))

            else:
                self.video_codec.setStringValue_('')
                self.video_srtp_lock.setHidden_(True)

            self.video_remote_endpoint.setStringValue_(
                '%s:%s' % (self.video_stream.stream.remote_rtp_address,
                           self.video_stream.stream.remote_rtp_port) if self.
                video_stream.stream.remote_rtp_address else '')

            if self.video_stream.stream.ice_active:
                ice_status = self.video_stream.ice_negotiation_status if self.video_stream.ice_negotiation_status is not None else ''
                if self.video_stream.stream.ice_active:
                    if self.video_stream.stream.local_rtp_candidate and self.video_stream.stream.remote_rtp_candidate:
                        if self.video_stream.stream.local_rtp_candidate.type.lower(
                        ) != 'relay' and self.video_stream.stream.remote_rtp_candidate.type.lower(
                        ) != 'relay':
                            if self.video_stream.stream.local_rtp_candidate.type.lower(
                            ) == 'host' and self.video_stream.stream.remote_rtp_candidate.type.lower(
                            ) == 'host':
                                ice_status = NSLocalizedString(
                                    "Host to Host", "Label")
                            else:
                                ice_status = NSLocalizedString(
                                    "Peer to Peer", "Label")
                        else:
                            ice_status = NSLocalizedString(
                                "Server Relayed", "Label")

            else:
                ice_status = self.video_stream.ice_negotiation_status if self.video_stream.ice_negotiation_status is not None else ''
                if ice_status == "All ICE checklists failed (PJNATH_EICEFAILED)":
                    ice_status = NSLocalizedString("Probing Failed", "Label")
                elif ice_status == "Remote answer doesn't support ICE":
                    ice_status = NSLocalizedString("Not Supported", "Label")

            self.video_ice_negotiation.setStringValue_(ice_status)
class FancyTabItem(NSView):
    switcher = None
    label = None
    badgeLabel = None
    busyIndicator = None
    closeButton = None
    mouseInside = False
    trackingArea = None
    cachedDragImage = None
    composing = False
    screen_sharing_active = False
    closeIcon = NSImage.imageNamed_(
        "NSStopProgressFreestandingTemplate").copy()
    composeIcon = NSImage.imageNamed_("pencil")
    screenIcon = NSImage.imageNamed_("display_red_16")

    badgeAttributes = None
    draggedOut = False

    @classmethod
    def initialize(self):
        paraStyle = NSParagraphStyle.defaultParagraphStyle().mutableCopy()
        paraStyle.setAlignment_(NSCenterTextAlignment)

        self.badgeAttributes = NSMutableDictionary.dictionaryWithObjectsAndKeys_(
            NSFont.boldSystemFontOfSize_(8), NSFontAttributeName,
            NSColor.whiteColor(), NSForegroundColorAttributeName, paraStyle,
            NSParagraphStyleAttributeName)

    def close(self):
        self.switcher = None
        self.item = None

    def dealloc(self):
        objc.super(FancyTabItem, self).dealloc()

    def initWithSwitcher_item_(self, switcher, item):
        self = NSView.initWithFrame_(self, NSMakeRect(0, 2, 100, 18))
        if self:
            self.closeIcon.setSize_(NSMakeSize(12, 12))
            self.closeButton = NSButton.alloc().initWithFrame_(
                NSMakeRect(3, 5, 12, 14))
            self.closeButton.setImagePosition_(NSImageOnly)
            self.closeButton.setButtonType_(NSMomentaryChangeButton)
            self.closeButton.cell().setBezelStyle_(NSSmallSquareBezelStyle)
            self.closeButton.setBordered_(False)
            self.closeButton.setImage_(self.closeIcon)
            self.closeButton.setAutoresizingMask_(NSViewMaxXMargin
                                                  | NSViewMaxYMargin)
            self.closeButton.setHidden_(True)
            self.addSubview_(self.closeButton)

            self.switcher = switcher
            self.item = item
        return self

    def updateTrackingAreas(self):
        if self.trackingArea:
            self.removeTrackingArea_(self.trackingArea)
        rect = NSZeroRect
        rect.size = self.frame().size
        tarea = NSTrackingArea.alloc().initWithRect_options_owner_userInfo_(
            rect,
            NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited,
            self, None)
        self.addTrackingArea_(tarea)
        self.trackingArea = tarea

    def setLabel_(self, label):
        if type(label) == NSString:
            self.label = label
        else:
            self.label = NSString.stringWithString_(label)
        frame = self.frame()
        frame.size.width = self.idealWidth()
        self.setFrame_(frame)

    def idealWidth(self):
        attribs = NSDictionary.dictionaryWithObject_forKey_(
            NSFont.systemFontOfSize_(11), NSFontAttributeName)
        size = self.label.sizeWithAttributes_(attribs)

        return size.width + 14 + 20

    def dragImage(self):
        if self.cachedDragImage:
            return self.cachedDragImage

        self.lockFocus()
        rep = NSBitmapImageRep.alloc().initWithFocusedViewRect_(self.bounds())
        self.unlockFocus()
        tabImage = NSImage.alloc().initWithSize_(rep.size())
        tabImage.addRepresentation_(rep)

        image = NSImage.alloc().initWithSize_(rep.size())
        image.addRepresentation_(rep)
        image.lockFocus()
        tabImage.drawAtPoint_fromRect_operation_fraction_(
            NSZeroPoint, NSZeroRect, NSCompositeSourceOver, 1.0)
        image.unlockFocus()

        return image

    def drawRect_(self, rect):
        r = self.bounds()
        r.size.width -= 0.5
        r.size.height += 4
        if self.draggedOut:
            NSColor.colorWithDeviceWhite_alpha_(0.4, 1.0).set()
            path = NSBezierPath.bezierPathWithRoundedRect_xRadius_yRadius_(
                r, 5, 5)
            path.fill()
        else:
            if self == self.switcher.activeItem():
                NSColor.controlColor().set()
            else:
                NSColor.colorWithDeviceWhite_alpha_(0.6, 1.0).set()
            path = NSBezierPath.bezierPathWithRoundedRect_xRadius_yRadius_(
                r, 5, 5)
            path.fill()
            NSColor.colorWithDeviceRed_green_blue_alpha_(0.3, 0.3, 0.3,
                                                         1.0).set()
            path.stroke()

        if self.badgeLabel and not self.mouseInside and not self.busyIndicator and not self.composing:
            # draw the number in redbadge indicator
            gradient = NSGradient.alloc().initWithStartingColor_endingColor_(
                NSColor.colorWithDeviceRed_green_blue_alpha_(0.9, 0.2, 0.2, 1),
                NSColor.colorWithDeviceRed_green_blue_alpha_(1.0, 0.2, 0.2, 1))
            size = self.badgeLabel.size()
            size.width += 4
            if size.width < 12:
                size.width = 12
            bez = NSBezierPath.bezierPathWithRoundedRect_xRadius_yRadius_(
                NSMakeRect(3, 5, size.width, 12), 6, 6)
            gradient.drawInBezierPath_angle_(bez, 90 + 45)
            self.badgeLabel.drawInRect_(NSMakeRect(3, 5, size.width, 12))

        if not self.mouseInside and not self.busyIndicator and self.composing:
            rect = NSZeroRect.copy()
            rect.size = self.composeIcon.size()
            self.composeIcon.drawAtPoint_fromRect_operation_fraction_(
                NSMakePoint(1, 3), rect, NSCompositeSourceOver, 1)

        if not self.busyIndicator and self.screen_sharing_active:
            rect = NSZeroRect.copy()
            rect.size = self.screenIcon.size()
            self.screenIcon.drawAtPoint_fromRect_operation_fraction_(
                NSMakePoint(17, 3), rect, NSCompositeSourceOver, 1)

        if not self.draggedOut:
            shadow = NSShadow.alloc().init()
            shadow.setShadowOffset_(NSMakeSize(0, -1))
            if self == self.switcher.activeItem():
                shadow.setShadowColor_(NSColor.whiteColor())
            else:
                shadow.setShadowColor_(
                    NSColor.colorWithDeviceWhite_alpha_(0.7, 1.0))
            para = NSParagraphStyle.defaultParagraphStyle().mutableCopy()
            para.setLineBreakMode_(NSLineBreakByTruncatingTail)
            para.setAlignment_(NSCenterTextAlignment)
            attribs = NSDictionary.dictionaryWithObjectsAndKeys_(
                NSFont.systemFontOfSize_(11), NSFontAttributeName, shadow,
                NSShadowAttributeName, para, NSParagraphStyleAttributeName)

            rect = self.bounds()
            rect.origin.y -= 3
            rect.origin.x += 20
            rect.origin.x = rect.origin.x + 12 if self.screen_sharing_active else rect.origin.x
            rect.size.width -= 46
            rect.size.width = rect.size.width - 12 if self.screen_sharing_active else rect.size.width
            self.label.drawInRect_withAttributes_(rect, attribs)

    def mouseEntered_(self, event):
        self.mouseInside = True
        self.closeButton.setHidden_(False)
        if self.busyIndicator:
            self.busyIndicator.setHidden_(True)

        self.setNeedsDisplay_(True)

    def mouseExited_(self, event):
        self.mouseInside = False
        self.closeButton.setHidden_(True)
        if self.busyIndicator:
            self.busyIndicator.setHidden_(False)
        self.setNeedsDisplay_(True)

    def mouseDown_(self, event):
        self.switcher.tabView.selectTabViewItem_(self.item)
        self.switcher.startedDragging_event_(self, event)

    def mouseDragged_(self, event):
        self.switcher.draggedItem_event_(self, event)
        if not self.cachedDragImage:
            self.cachedDragImage = self.dragImage()

    def mouseUp_(self, event):
        self.switcher.finishedDraging_event_(self, event)
        self.cachedDragImage = None

    def setBadgeLabel_(self, text):
        if text:
            self.badgeLabel = NSAttributedString.alloc(
            ).initWithString_attributes_(text, self.badgeAttributes)
        else:
            self.badgeLabel = None
        self.setNeedsDisplay_(True)

    def setDraggedOut_(self, flag):
        self.draggedOut = flag
        self.setNeedsDisplay_(True)
        if self.busyIndicator:
            self.busyIndicator.setHidden_(flag)

    def setComposing_(self, flag):
        self.composing = flag
        self.setNeedsDisplay_(True)

    def setScreenSharing_(self, flag):
        self.screen_sharing_active = flag
        self.setNeedsDisplay_(True)

    def setBusy_(self, flag):
        if flag:
            if not self.busyIndicator:
                self.busyIndicator = NSProgressIndicator.alloc(
                ).initWithFrame_(NSMakeRect(3, 4, 15, 15))
                self.busyIndicator.setControlSize_(NSSmallControlSize)
                self.busyIndicator.setIndeterminate_(True)
                self.busyIndicator.setStyle_(NSProgressIndicatorSpinningStyle)
                self.busyIndicator.startAnimation_(None)
                self.busyIndicator.setAutoresizingMask_(NSViewMaxXMargin
                                                        | NSViewMaxYMargin)
                self.addSubview_(self.busyIndicator)
                self.closeButton.setHidden_(True)
        else:
            if self.busyIndicator:
                self.busyIndicator.stopAnimation_(None)
                self.busyIndicator.removeFromSuperview()
                self.busyIndicator = None
                self.closeButton.setHidden_(not self.mouseInside)
class ContactCell(NSTextFieldCell):
    contact = None
    view = None
    frame = None

    audioIcon = NSImage.imageNamed_("audio_16")
    audioHoldIcon = NSImage.imageNamed_("paused_16")
    chatIcon = NSImage.imageNamed_("pencil_16")
    screenIcon = NSImage.imageNamed_("display_16")
    locationIcon = NSImage.imageNamed_("location")
    nightIcon = NSImage.imageNamed_("moon")

    style = NSParagraphStyle.defaultParagraphStyle().mutableCopy()
    style.setLineBreakMode_(NSLineBreakByTruncatingTail)
    firstLineAttributes = NSDictionary.dictionaryWithObjectsAndKeys_(
        NSFont.systemFontOfSize_(12.0), NSFontAttributeName, style,
        NSParagraphStyleAttributeName)
    firstLineAttributes_highlighted = NSDictionary.dictionaryWithObjectsAndKeys_(
        NSFont.systemFontOfSize_(12.0), NSFontAttributeName,
        NSColor.whiteColor(), NSForegroundColorAttributeName, style,
        NSParagraphStyleAttributeName)
    secondLineAttributes = NSDictionary.dictionaryWithObjectsAndKeys_(
        NSFont.systemFontOfSize_(NSFont.labelFontSize() - 1),
        NSFontAttributeName, NSColor.grayColor(),
        NSForegroundColorAttributeName, style, NSParagraphStyleAttributeName)
    secondLineAttributes_highlighted = NSDictionary.dictionaryWithObjectsAndKeys_(
        NSFont.systemFontOfSize_(NSFont.labelFontSize() - 1),
        NSFontAttributeName, NSColor.whiteColor(),
        NSForegroundColorAttributeName, style, NSParagraphStyleAttributeName)

    def setContact_(self, contact):
        self.contact = contact

    def setMessageIcon_(self, icon):
        self.messageIcon = icon

    def drawingRectForBounds_(self, rect):
        return rect

    def cellSize(self):
        if self.contact is None:
            return objc.super(ContactCell, self).cellSize()
        return NSMakeSize(100, 30)

    def drawWithFrame_inView_(self, frame, view):
        if self.contact is None:
            return objc.super(ContactCell,
                              self).drawWithFrame_inView_(frame, view)

        self.frame = frame
        self.view = view

        try:
            icon = self.contact.avatar.icon
            self.drawIcon(icon, 2, self.frame.origin.y + 3, 28, 28)

            self.drawActiveMedia()
            self.drawFirstLine()
            self.drawSecondLine()
            self.drawPresenceIcon()
        except Exception:
            pass

    @objc.python_method
    def drawFirstLine(self):
        frame = self.frame
        frame.origin.x = 35
        frame.origin.y += 2

        rect = NSMakeRect(frame.origin.x, frame.origin.y,
                          frame.size.width - 10, frame.size.height)
        attrs = self.firstLineAttributes if not self.isHighlighted(
        ) else self.firstLineAttributes_highlighted
        self.stringValue().drawInRect_withAttributes_(rect, attrs)

    @objc.python_method
    def drawSecondLine(self):
        frame = self.frame
        frame.origin.y += 15
        if self.contact.detail:
            rect = NSMakeRect(frame.origin.x, frame.origin.y,
                              frame.size.width - 25, frame.size.height)
            attrs = self.secondLineAttributes if not self.isHighlighted(
            ) else self.secondLineAttributes_highlighted
            self.contact.detail.drawInRect_withAttributes_(rect, attrs)

    @objc.python_method
    def drawActiveMedia(self):
        if type(self.contact) not in (BlinkConferenceContact,
                                      BlinkMyselfConferenceContact):
            return

        padding = 16
        left = self.frame.size.width - 8
        if 'audio-onhold' in self.contact.active_media:
            left = left - padding
            self.drawIcon(self.audioHoldIcon, left, self.frame.origin.y + 14,
                          16, 16)
        elif 'audio' in self.contact.active_media:
            left = left - padding
            self.drawIcon(self.audioIcon, left, self.frame.origin.y + 14, 16,
                          16)

        if 'message' in self.contact.active_media:
            left = left - padding
            self.drawIcon(self.chatIcon, left, self.frame.origin.y + 14, 16,
                          16)

        if 'screen' in self.contact.active_media:
            left = left - padding - 2
            self.drawIcon(self.screenIcon, left, self.frame.origin.y + 14, 16,
                          16)

    @objc.python_method
    def drawPresenceIcon(self):
        status = 'offline'
        if type(self.contact) is BlinkMyselfConferenceContact:
            account = self.contact.account
            if account.enabled and account.presence.enabled:
                settings = SIPSimpleSettings()
                status = settings.presence_state.status.lower()
        elif type(self.contact) is BlinkConferenceContact:
            blink_contact = self.contact.presence_contact
            if not isinstance(blink_contact, BlinkPresenceContact):
                return
            if not blink_contact.contact.presence.subscribe:
                return
            status = presence_status_for_contact(blink_contact)
        elif type(self.contact) is BlinkHistoryViewerContact:
            blink_contact = self.contact.presence_contact
            if not isinstance(blink_contact, BlinkPresenceContact):
                return
            if not blink_contact.contact.presence.subscribe:
                return
            status = presence_status_for_contact(blink_contact)

        elif type(self.contact) is HistoryBlinkContact:
            blink_contact = self.contact.contact
            if not isinstance(blink_contact, BlinkPresenceContact):
                return
            if not blink_contact.contact.presence.subscribe:
                return
            status = presence_status_for_contact(blink_contact)
        elif isinstance(self.contact, BlinkPresenceContact):
            blink_contact = self.contact
            if not blink_contact.contact.presence.subscribe:
                return
            status = presence_status_for_contact(blink_contact)
        elif type(self.contact) is BonjourBlinkContact:
            account = BonjourAccount()
            if not account.presence.enabled:
                return
            blink_contact = self.contact
            status = presence_status_for_contact(blink_contact)
        elif type(self.contact) is SystemAddressBookBlinkContact:
            return
        elif type(self.contact) is LdapSearchResultContact:
            return
        elif type(self.contact) is SearchResultContact:
            return

        if not status:
            return
        try:
            icon = presence_status_icons[status]
        except KeyError:
            pass

        has_locations = None
        if isinstance(self.contact,
                      (BlinkOnlineContact, BlinkPresenceContact)):
            try:
                has_locations = any(device['location'] for device in list(
                    self.contact.presence_state['devices'].values())
                                    if device['location'] is not None)
            except KeyError:
                pass

        frame = self.frame
        frame.origin.y -= 17
        #if has_locations:
        #    left = self.view.frame().size.width - 22
        #    self.drawIcon(self.locationIcon, left, self.frame.origin.y +14, 16, 16)

        # presence bar
        frame.size.width = 5
        if type(self.contact) in (BlinkConferenceContact,
                                  BlinkMyselfConferenceContact):
            frame.size.height = 14
            frame.origin.y += 15
        frame.origin.x = self.view.frame().size.width - 6

        rect = NSInsetRect(frame, 0, 0)

        if status == 'available':
            NSColor.greenColor().set()
        elif status == 'away':
            NSColor.yellowColor().set()
        elif status == 'busy':
            NSColor.redColor().set()
        else:
            NSColor.whiteColor().set()

        border = NSBezierPath.bezierPathWithRoundedRect_xRadius_yRadius_(
            rect, 2.0, 2.0)
        border.setLineWidth_(0.08)
        border.fill()
        NSColor.blackColor().set()
        border.stroke()

        # sleep icon
        if isinstance(self.contact,
                      (BlinkOnlineContact, BlinkPresenceContact)):
            if self.contact.presence_state['time_offset'] is not None:
                ctime = datetime.datetime.utcnow(
                ) + self.contact.presence_state['time_offset']
                hour = int(ctime.strftime("%H"))
                if hour > 21 or hour < 7:
                    left = self.view.frame().size.width - 26
                    self.drawIcon(self.nightIcon, left,
                                  self.frame.origin.y + 14, 16, 16)

    @objc.python_method
    def drawIcon(self, icon, origin_x, origin_y, size_x, size_y):
        size = icon.size()
        if not size or not size.height:
            return
        rect = NSMakeRect(0, 0, size.width, size.height)
        trect = NSMakeRect(origin_x, origin_y,
                           (size_y / size.height) * size.width, size_x)
        icon.drawInRect_fromRect_operation_fraction_respectFlipped_hints_(
            trect, rect, NSCompositeSourceOver, 1.0, True, None)
 def userClickedToolbarButton_(self, sender):
     if sender.tag() == 100:
        self.fitWindowButton.setState_(NSOffState if self.fitWindowButton.state() == NSOnState else NSOnState)
        self.fitWindowButton.setImage_(NSImage.imageNamed_('shrinktofit-pressed' if not self.screensharing_fit_window else 'shrinktofit'))
        self.screensharing_fit_window = False if self.screensharing_fit_window else True
        self.startLoading()
    def __init__(self):
        if self:
            BlinkLogger().log_debug('Starting History Viewer')
            NSBundle.loadNibNamed_owner_("HistoryViewer", self)

            self.all_contacts = BlinkHistoryViewerContact('Any Address', name='All Contacts')
            self.bonjour_contact = BlinkHistoryViewerContact('bonjour.local', name='Bonjour Neighbours', icon=NSImage.imageNamed_("NSBonjour"))

            self.notification_center = NotificationCenter()
            self.notification_center.add_observer(self, name='ChatViewControllerDidDisplayMessage')
            self.notification_center.add_observer(self, name='AudioCallLoggedToHistory')
            self.notification_center.add_observer(self, name='BlinkContactsHaveChanged')
            self.notification_center.add_observer(self, name='BlinkTableViewSelectionChaged')
            self.notification_center.add_observer(self, name='BlinkConferenceContactPresenceHasChanged')
            self.notification_center.add_observer(self, name='BlinkShouldTerminate')

            self.searchText.cell().setSendsSearchStringImmediately_(True)
            self.searchText.cell().setPlaceholderString_(NSLocalizedString("Type text and press Enter", "Placeholder text"))

            self.chatViewController.setContentFile_(NSBundle.mainBundle().pathForResource_ofType_("ChatView", "html"))
            self.chatViewController.setHandleScrolling_(False)
            self.entriesView.setShouldCloseWithWindow_(False)

            for c in ('remote_uri', 'local_uri', 'date', 'type'):
                col = self.indexTable.tableColumnWithIdentifier_(c)
                descriptor = NSSortDescriptor.alloc().initWithKey_ascending_(c, True)
                col.setSortDescriptorPrototype_(descriptor)

            self.chat_history = ChatHistory()
            self.session_history = SessionHistory()
            self.setPeriod(1)

            self.selectedTableView = self.contactTable