예제 #1
0
  /**
   * Adds resources for contact.
   *
   * @param tip the tool tip
   * @param protocolContact the protocol contact, which resources we're looking for
   */
  private void addContactResourceTooltipLines(ExtendedTooltip tip, Contact protocolContact) {
    Collection<ContactResource> contactResources = protocolContact.getResources();

    if (contactResources == null) return;

    Iterator<ContactResource> resourcesIter = contactResources.iterator();

    while (resourcesIter.hasNext()) {
      ContactResource contactResource = resourcesIter.next();

      // We only add the status icon if we have more than one resources,
      // otherwise it will always be identical to the contact status icon.
      ImageIcon protocolStatusIcon = null;
      if (contactResources.size() > 1) {
        protocolStatusIcon =
            ImageLoader.getIndexedProtocolIcon(
                ImageUtils.getBytesInImage(contactResource.getPresenceStatus().getStatusIcon()),
                protocolContact.getProtocolProvider());
      }

      String resourceName =
          (contactResource.getPriority() >= 0)
              ? contactResource.getResourceName() + " (" + contactResource.getPriority() + ")"
              : contactResource.getResourceName();

      if (protocolStatusIcon == null) tip.addSubLine(protocolStatusIcon, resourceName, 27);
      else tip.addSubLine(protocolStatusIcon, resourceName, 20);
    }

    tip.revalidate();
    tip.repaint();
  }
  /**
   * Initializes custom contact action buttons.
   *
   * @param contactActionButtons the list of buttons to initialize
   * @param gridX the X grid of the first button
   * @param xBounds the x bounds of the first button
   * @return the new grid X coordinate after adding all the buttons
   */
  private int initGroupActionButtons(
      Collection<SIPCommButton> contactActionButtons, int gridX, int xBounds) {
    // Reinit the labels to take the whole horizontal space.
    addLabels(gridX + contactActionButtons.size());

    Iterator<SIPCommButton> actionsIter = contactActionButtons.iterator();
    while (actionsIter.hasNext()) {
      final SIPCommButton actionButton = actionsIter.next();

      // We need to explicitly remove the buttons from the tooltip manager,
      // because we're going to manager the tooltip ourselves in the
      // DefaultTreeContactList class. We need to do this in order to have
      // a different tooltip for every button and for non button area.
      ToolTipManager.sharedInstance().unregisterComponent(actionButton);

      if (customActionButtonsUIGroup == null)
        customActionButtonsUIGroup = new LinkedList<JButton>();

      customActionButtonsUIGroup.add(actionButton);

      xBounds += addButton(actionButton, ++gridX, xBounds, false);
    }

    return gridX;
  }
  /**
   * Notify all listeners of the corresponding account detail change event.
   *
   * @param source the protocol provider service source
   * @param eventID the int ID of the event to dispatch
   * @param oldValue the value that the changed property had before the change occurred.
   * @param newValue the value that the changed property currently has (after the change has
   *     occurred).
   */
  public void fireServerStoredDetailsChangeEvent(
      ProtocolProviderService source, int eventID, Object oldValue, Object newValue) {
    ServerStoredDetailsChangeEvent evt =
        new ServerStoredDetailsChangeEvent(source, eventID, oldValue, newValue);

    Collection<ServerStoredDetailsChangeListener> listeners;
    synchronized (serverStoredDetailsListeners) {
      listeners = new ArrayList<ServerStoredDetailsChangeListener>(serverStoredDetailsListeners);
    }

    if (logger.isDebugEnabled())
      logger.debug(
          "Dispatching a Contact Property Change Event to"
              + listeners.size()
              + " listeners. Evt="
              + evt);

    for (ServerStoredDetailsChangeListener listener : listeners)
      listener.serverStoredDetailsChanged(evt);
  }
  /**
   * Initializes buttons panel.
   *
   * @param uiGroup the <tt>UIGroup</tt> for which we initialize the button panel
   */
  private void initButtonsPanel(UIGroup uiGroup) {
    if (!isSelected) return;

    int x = (statusIcon == null ? 0 : statusIcon.getIconWidth()) + LEFT_BORDER + H_GAP;
    int gridX = 0;

    // The list of the actions
    // we will create a button for every action
    Collection<SIPCommButton> contactActions = uiGroup.getCustomActionButtons();

    int lastGridX = gridX;
    if (contactActions != null && contactActions.size() > 0) {
      lastGridX = initGroupActionButtons(contactActions, gridX, x);
    } else {
      addLabels(gridX);
    }

    if (lastAddedButton != null) setButtonBg(lastAddedButton, lastGridX, true);

    this.setBounds(0, 0, treeContactList.getWidth(), getPreferredSize().height);
  }
예제 #5
0
  /**
   * Gathers Jingle Nodes candidates for all host <tt>Candidate</tt>s that are already present in
   * the specified <tt>component</tt>. This method relies on the specified <tt>component</tt> to
   * already contain all its host candidates so that it would resolve them.
   *
   * @param component the {@link Component} that we'd like to gather candidate Jingle Nodes
   *     <tt>Candidate</tt>s for
   * @return the <tt>LocalCandidate</tt>s gathered by this <tt>CandidateHarvester</tt>
   */
  @Override
  public synchronized Collection<LocalCandidate> harvest(Component component) {
    logger.info("harvest Jingle Nodes");

    Collection<LocalCandidate> candidates = new HashSet<LocalCandidate>();
    String ip = null;
    int port = -1;

    /* if we have already a candidate (RTCP) allocated, get it */
    if (localAddressSecond != null && relayedAddressSecond != null) {
      LocalCandidate candidate =
          createJingleNodesCandidate(relayedAddressSecond, component, localAddressSecond);

      // try to add the candidate to the component and then only add it to
      // the harvest not redundant (not sure how it could be red. but ...)
      if (component.addLocalCandidate(candidate)) {
        candidates.add(candidate);
      }

      localAddressSecond = null;
      relayedAddressSecond = null;
      return candidates;
    }

    XMPPConnection conn = serviceNode.getConnection();
    JingleChannelIQ ciq = null;

    if (serviceNode != null) {
      final TrackerEntry preferred = serviceNode.getPreferedRelay();

      if (preferred != null) {
        ciq = SmackServiceNode.getChannel(conn, preferred.getJid());
      }
    }

    if (ciq != null) {
      ip = ciq.getHost();
      port = ciq.getRemoteport();

      if (logger.isInfoEnabled()) {
        logger.info(
            "JN relay: " + ip + " remote port:" + port + " local port: " + ciq.getLocalport());
      }

      if (ip == null || ciq.getRemoteport() == 0) {
        logger.warn("JN relay ignored because ip was null or port 0");
        return candidates;
      }

      // Drop the scope or interface name if the relay sends it
      // along in its IPv6 address. The scope/ifname is only valid on the
      // host that owns the IP and we don't need it here.
      int scopeIndex = ip.indexOf('%');
      if (scopeIndex > 0) {
        logger.warn("Dropping scope from assumed IPv6 address " + ip);
        ip = ip.substring(0, scopeIndex);
      }

      /* RTP */
      TransportAddress relayedAddress = new TransportAddress(ip, port, Transport.UDP);
      TransportAddress localAddress = new TransportAddress(ip, ciq.getLocalport(), Transport.UDP);

      LocalCandidate local = createJingleNodesCandidate(relayedAddress, component, localAddress);

      /* RTCP */
      relayedAddressSecond = new TransportAddress(ip, port + 1, Transport.UDP);
      localAddressSecond = new TransportAddress(ip, ciq.getLocalport() + 1, Transport.UDP);

      // try to add the candidate to the component and then only add it to
      // the harvest not redundant (not sure how it could be red. but ...)
      if (component.addLocalCandidate(local)) {
        candidates.add(local);
      }
    }

    return candidates;
  }
  /**
   * Initializes buttons panel.
   *
   * @param uiContact the <tt>UIContact</tt> for which we initialize the button panel
   */
  private void initButtonsPanel(UIContact uiContact) {
    this.remove(chatButton);
    this.remove(callButton);
    this.remove(callVideoButton);
    this.remove(desktopSharingButton);
    this.remove(addContactButton);

    clearCustomActionButtons();

    if (!isSelected) return;

    UIContactDetail imContact = null;
    // For now we support instance messaging only for contacts in our
    // contact list until it's implemented for external source contacts.
    if (uiContact.getDescriptor() instanceof MetaContact)
      imContact = uiContact.getDefaultContactDetail(OperationSetBasicInstantMessaging.class);

    int x = (statusIcon == null ? 0 : statusIcon.getIconWidth()) + LEFT_BORDER + H_GAP;

    // Re-initialize the x grid.
    constraints.gridx = 0;
    int gridX = 0;

    if (imContact != null) {
      x += addButton(chatButton, ++gridX, x, false);
    }

    UIContactDetail telephonyContact =
        uiContact.getDefaultContactDetail(OperationSetBasicTelephony.class);

    // Check if contact has additional phone numbers, if yes show the
    // call button
    ContactPhoneUtil contactPhoneUtil = null;

    // check for phone stored in contact info only
    // if telephony contact is missing
    if (uiContact.getDescriptor() != null
        && uiContact.getDescriptor() instanceof MetaContact
        && telephonyContact == null) {
      contactPhoneUtil = ContactPhoneUtil.getPhoneUtil((MetaContact) uiContact.getDescriptor());

      MetaContact metaContact = (MetaContact) uiContact.getDescriptor();
      Iterator<Contact> contacts = metaContact.getContacts();

      while (contacts.hasNext()) // && !hasPhone)
      {
        Contact contact = contacts.next();

        if (!contact.getProtocolProvider().isRegistered()) continue;

        contactPhoneUtil.addDetailsResponseListener(
            contact, new DetailsListener(treeNode, callButton, uiContact));
      }
    }

    // for SourceContact in history that do not support telephony, we
    // show the button but disabled
    List<ProtocolProviderService> providers =
        AccountUtils.getOpSetRegisteredProviders(OperationSetBasicTelephony.class, null, null);

    if ((telephonyContact != null && telephonyContact.getAddress() != null)
        || (contactPhoneUtil != null && contactPhoneUtil.isCallEnabled() && providers.size() > 0)) {
      x += addButton(callButton, ++gridX, x, false);
    }

    UIContactDetail videoContact =
        uiContact.getDefaultContactDetail(OperationSetVideoTelephony.class);

    if (videoContact != null
        || (contactPhoneUtil != null && contactPhoneUtil.isVideoCallEnabled())) {
      x += addButton(callVideoButton, ++gridX, x, false);
    }

    UIContactDetail desktopContact =
        uiContact.getDefaultContactDetail(OperationSetDesktopSharingServer.class);

    if (desktopContact != null
        || (contactPhoneUtil != null && contactPhoneUtil.isDesktopSharingEnabled())) {
      x += addButton(desktopSharingButton, ++gridX, x, false);
    }

    // enable add contact button if contact source has indicated
    // that this is possible
    if (uiContact.getDescriptor() instanceof SourceContact
        && uiContact.getDefaultContactDetail(OperationSetPersistentPresence.class) != null
        && AccountUtils.getOpSetRegisteredProviders(
                    OperationSetPersistentPresence.class, null, null)
                .size()
            > 0
        && !ConfigurationUtils.isAddContactDisabled()) {
      x += addButton(addContactButton, ++gridX, x, false);
    }

    // The list of the contact actions
    // we will create a button for every action
    Collection<SIPCommButton> contactActions = uiContact.getContactCustomActionButtons();

    int lastGridX = gridX;
    if (contactActions != null && contactActions.size() > 0) {
      lastGridX = initContactActionButtons(contactActions, gridX, x);
    } else {
      addLabels(gridX);
    }

    if (lastAddedButton != null) setButtonBg(lastAddedButton, lastGridX, true);

    this.setBounds(0, 0, treeContactList.getWidth(), getPreferredSize().height);
  }