Example #1
0
  /**
   * Sends the given file through this chat transport file transfer operation set.
   *
   * @param file the file to send
   * @return the <tt>FileTransfer</tt> object charged to transfer the file
   * @throws Exception if anything goes wrong
   */
  public FileTransfer sendFile(File file) throws Exception {
    // If this chat transport does not support instant messaging we do
    // nothing here.
    if (!allowsFileTransfer()) return null;

    OperationSetFileTransfer ftOpSet =
        contact.getProtocolProvider().getOperationSet(OperationSetFileTransfer.class);

    if (FileUtils.isImage(file.getName())) {
      // Create a thumbnailed file if possible.
      OperationSetThumbnailedFileFactory tfOpSet =
          contact.getProtocolProvider().getOperationSet(OperationSetThumbnailedFileFactory.class);

      if (tfOpSet != null) {
        byte[] thumbnail = getFileThumbnail(file);

        if (thumbnail != null && thumbnail.length > 0) {
          file =
              tfOpSet.createFileWithThumbnail(
                  file, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, "image/png", thumbnail);
        }
      }
    }
    return ftOpSet.sendFile(contact, file);
  }
Example #2
0
  /**
   * Sends a typing notification state.
   *
   * @param typingState the typing notification state to send
   * @return the result of this operation. One of the TYPING_NOTIFICATION_XXX constants defined in
   *     this class
   */
  public int sendTypingNotification(int typingState) {
    // If this chat transport does not support sms messaging we do
    // nothing here.
    if (!allowsTypingNotifications()) return -1;

    ProtocolProviderService protocolProvider = contact.getProtocolProvider();
    OperationSetTypingNotifications tnOperationSet =
        protocolProvider.getOperationSet(OperationSetTypingNotifications.class);

    // if protocol is not registered or contact is offline don't
    // try to send typing notifications
    if (protocolProvider.isRegistered()
        && contact.getPresenceStatus().getStatus() >= PresenceStatus.ONLINE_THRESHOLD) {
      try {
        tnOperationSet.sendTypingNotification(contact, typingState);

        return ChatPanel.TYPING_NOTIFICATION_SUCCESSFULLY_SENT;
      } catch (Exception ex) {
        logger.error("Failed to send typing notifications.", ex);

        return ChatPanel.TYPING_NOTIFICATION_SEND_FAILED;
      }
    }

    return ChatPanel.TYPING_NOTIFICATION_SEND_FAILED;
  }
Example #3
0
  /**
   * Sends the given sms message trough this chat transport.
   *
   * @param phoneNumber phone number of the destination
   * @param messageText The message to send.
   * @throws Exception if the send operation is interrupted
   */
  public void sendSmsMessage(String phoneNumber, String messageText) throws Exception {
    // If this chat transport does not support sms messaging we do
    // nothing here.
    if (!allowsSmsMessage()) return;

    SMSManager.sendSMS(contact.getProtocolProvider(), phoneNumber, messageText);
  }
Example #4
0
  /**
   * Determines whether this chat transport supports the supplied content type
   *
   * @param contentType the type we want to check
   * @return <tt>true</tt> if the chat transport supports it and <tt>false</tt> otherwise.
   */
  public boolean isContentTypeSupported(String contentType) {
    OperationSetBasicInstantMessaging imOpSet =
        contact.getProtocolProvider().getOperationSet(OperationSetBasicInstantMessaging.class);

    if (imOpSet != null) return imOpSet.isContentTypeSupported(contentType);
    else return false;
  }
Example #5
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();
  }
Example #6
0
  /**
   * Returns <code>true</code> if this chat transport supports typing notifications, otherwise
   * returns <code>false</code>.
   *
   * @return <code>true</code> if this chat transport supports typing notifications, otherwise
   *     returns <code>false</code>.
   */
  public boolean allowsTypingNotifications() {
    Object tnOpSet =
        contact.getProtocolProvider().getOperationSet(OperationSetTypingNotifications.class);

    if (tnOpSet != null) return true;
    else return false;
  }
Example #7
0
  /**
   * Removes the instant message listener from this chat transport.
   *
   * @param l The message listener to remove.
   */
  public void removeInstantMessageListener(MessageListener l) {
    // If this chat transport does not support instant messaging we do
    // nothing here.
    if (!allowsInstantMessage()) return;

    OperationSetBasicInstantMessaging imOpSet =
        contact.getProtocolProvider().getOperationSet(OperationSetBasicInstantMessaging.class);

    imOpSet.removeMessageListener(l);
  }
Example #8
0
  /**
   * Removes the given sms message listener from this chat transport.
   *
   * @param l The message listener to remove.
   */
  public void removeSmsMessageListener(MessageListener l) {
    // If this chat transport does not support sms messaging we do
    // nothing here.
    if (!allowsSmsMessage()) return;

    OperationSetSmsMessaging smsOpSet =
        contact.getProtocolProvider().getOperationSet(OperationSetSmsMessaging.class);

    smsOpSet.removeMessageListener(l);
  }
Example #9
0
  /**
   * Whether a dialog need to be opened so the user can enter the destination number.
   *
   * @return <tt>true</tt> if dialog needs to be open.
   */
  public boolean askForSMSNumber() {
    // If this chat transport does not support sms messaging we do
    // nothing here.
    if (!allowsSmsMessage()) return false;

    OperationSetSmsMessaging smsOpSet =
        contact.getProtocolProvider().getOperationSet(OperationSetSmsMessaging.class);

    return smsOpSet.askForNumber(contact);
  }
Example #10
0
  /**
   * If sending im is supported check it for supporting html messages if a font is set. As it can be
   * slow make sure its not on our way
   */
  private void checkImCaps() {
    if (ConfigurationUtils.getChatDefaultFontFamily() != null
        && ConfigurationUtils.getChatDefaultFontSize() > 0) {
      OperationSetBasicInstantMessaging imOpSet =
          contact.getProtocolProvider().getOperationSet(OperationSetBasicInstantMessaging.class);

      if (imOpSet != null)
        imOpSet.isContentTypeSupported(OperationSetBasicInstantMessaging.HTML_MIME_TYPE, contact);
    }
  }
Example #11
0
  /**
   * Returns <code>true</code> if this chat transport supports message corrections and false
   * otherwise.
   *
   * @return <code>true</code> if this chat transport supports message corrections and false
   *     otherwise.
   */
  public boolean allowsMessageCorrections() {
    OperationSetContactCapabilities capOpSet =
        getProtocolProvider().getOperationSet(OperationSetContactCapabilities.class);

    if (capOpSet != null) {
      return capOpSet.getOperationSet(contact, OperationSetMessageCorrection.class) != null;
    } else {
      return contact.getProtocolProvider().getOperationSet(OperationSetMessageCorrection.class)
          != null;
    }
  }
Example #12
0
  /**
   * Implements ListSelectionListener.valueChanged. Enables or disables call and hangup buttons
   * depending on the selection in the contactlist.
   */
  public void valueChanged(ListSelectionEvent e) {
    Object o = mainFrame.getContactListPanel().getContactList().getSelectedValue();

    if ((e.getFirstIndex() != -1 || e.getLastIndex() != -1) && (o instanceof MetaContact)) {
      setCallMetaContact(true);

      // Switch automatically to the appropriate pps in account selector
      // box and enable callButton if telephony is supported.
      Contact contact = ((MetaContact) o).getDefaultContact(OperationSetBasicTelephony.class);

      if (contact != null) {
        callButton.setEnabled(true);

        if (contact.getProtocolProvider().isRegistered())
          getAccountSelectorBox().setSelected(contact.getProtocolProvider());
      } else {
        callButton.setEnabled(false);
      }
    } else if (phoneNumberCombo.isComboFieldEmpty()) {
      callButton.setEnabled(false);
    }
  }
Example #13
0
  /**
   * Returns <code>true</code> if this chat transport supports sms messaging, otherwise returns
   * <code>false</code>.
   *
   * @return <code>true</code> if this chat transport supports sms messaging, otherwise returns
   *     <code>false</code>.
   */
  public boolean allowsSmsMessage() {
    // First try to ask the capabilities operation set if such is
    // available.
    OperationSetContactCapabilities capOpSet =
        getProtocolProvider().getOperationSet(OperationSetContactCapabilities.class);

    if (capOpSet != null) {
      if (capOpSet.getOperationSet(contact, OperationSetSmsMessaging.class) != null) {
        return true;
      }
    } else if (contact.getProtocolProvider().getOperationSet(OperationSetSmsMessaging.class)
        != null) return true;

    return false;
  }
Example #14
0
  /**
   * Returns the display details for the underlying <tt>MetaContact</tt>.
   *
   * @return the display details for the underlying <tt>MetaContact</tt>
   */
  public String getDisplayDetails() {
    String displayDetails = null;

    Iterator<Contact> protoContacts = metaContact.getContacts();

    String subscriptionDetails = null;

    while (protoContacts.hasNext()) {
      Contact protoContact = protoContacts.next();

      OperationSetExtendedAuthorizations authOpSet =
          protoContact
              .getProtocolProvider()
              .getOperationSet(OperationSetExtendedAuthorizations.class);

      if (authOpSet != null
          && authOpSet.getSubscriptionStatus(protoContact) != null
          && !authOpSet.getSubscriptionStatus(protoContact).equals(SubscriptionStatus.Subscribed)) {
        SubscriptionStatus status = authOpSet.getSubscriptionStatus(protoContact);

        if (status.equals(SubscriptionStatus.SubscriptionPending))
          subscriptionDetails =
              GuiActivator.getResources().getI18NString("service.gui.WAITING_AUTHORIZATION");
        else if (status.equals(SubscriptionStatus.NotSubscribed))
          subscriptionDetails =
              GuiActivator.getResources().getI18NString("service.gui.NOT_AUTHORIZED");
      } else if (protoContact.getStatusMessage() != null
          && protoContact.getStatusMessage().length() > 0) {
        subscribed = true;
        displayDetails = protoContact.getStatusMessage();
        break;
      } else {
        subscribed = true;
      }
    }

    if ((displayDetails == null || displayDetails.length() <= 0)
        && !subscribed
        && subscriptionDetails != null
        && subscriptionDetails.length() > 0) displayDetails = subscriptionDetails;

    return displayDetails;
  }
Example #15
0
  /**
   * Sends <tt>message</tt> as a message correction through this transport, specifying the mime type
   * (html or plain text) and the id of the message to replace.
   *
   * @param message The message to send.
   * @param mimeType The mime type of the message to send: text/html or text/plain.
   * @param correctedMessageUID The ID of the message being corrected by this message.
   */
  public void correctInstantMessage(String message, String mimeType, String correctedMessageUID) {
    if (!allowsMessageCorrections()) {
      return;
    }

    OperationSetMessageCorrection mcOpSet =
        contact.getProtocolProvider().getOperationSet(OperationSetMessageCorrection.class);

    Message msg;
    if (mimeType.equals(OperationSetBasicInstantMessaging.HTML_MIME_TYPE)
        && mcOpSet.isContentTypeSupported(OperationSetBasicInstantMessaging.HTML_MIME_TYPE)) {
      msg =
          mcOpSet.createMessage(
              message, OperationSetBasicInstantMessaging.HTML_MIME_TYPE, "utf-8", "");
    } else {
      msg = mcOpSet.createMessage(message);
    }

    mcOpSet.correctMessage(contact, contactResource, msg, correctedMessageUID);
  }
Example #16
0
  /**
   * Sends the given instant message through this chat transport, by specifying the mime type (html
   * or plain text).
   *
   * @param message The message to send.
   * @param mimeType The mime type of the message to send: text/html or text/plain.
   * @throws Exception if the send operation is interrupted
   */
  public void sendInstantMessage(String message, String mimeType) throws Exception {
    // If this chat transport does not support instant messaging we do
    // nothing here.
    if (!allowsInstantMessage()) return;

    OperationSetBasicInstantMessaging imOpSet =
        contact.getProtocolProvider().getOperationSet(OperationSetBasicInstantMessaging.class);

    Message msg;
    if (mimeType.equals(OperationSetBasicInstantMessaging.HTML_MIME_TYPE)
        && imOpSet.isContentTypeSupported(OperationSetBasicInstantMessaging.HTML_MIME_TYPE)) {
      msg =
          imOpSet.createMessage(
              message, OperationSetBasicInstantMessaging.HTML_MIME_TYPE, "utf-8", "");
    } else {
      msg = imOpSet.createMessage(message);
    }

    if (contactResource != null) imOpSet.sendInstantMessage(contact, contactResource, msg);
    else imOpSet.sendInstantMessage(contact, ContactResource.BASE_RESOURCE, msg);
  }
Example #17
0
    /**
     * Creates an instance of <tt>MetaContactDetail</tt> by specifying the underlying protocol
     * <tt>Contact</tt>.
     *
     * @param contact the protocol contact, on which this implementation is based
     */
    public MetaContactDetail(Contact contact) {
      super(
          contact.getAddress(),
          contact.getDisplayName(),
          new ImageIcon(contact.getPresenceStatus().getStatusIcon()),
          contact);

      this.contact = contact;

      ProtocolProviderService parentProvider = contact.getProtocolProvider();

      Iterator<Class<? extends OperationSet>> opSetClasses =
          parentProvider.getSupportedOperationSetClasses().iterator();

      while (opSetClasses.hasNext()) {
        Class<? extends OperationSet> opSetClass = opSetClasses.next();

        addPreferredProtocolProvider(opSetClass, parentProvider);
        addPreferredProtocol(opSetClass, parentProvider.getProtocolName());
      }
    }
Example #18
0
  /**
   * Creates an instance of <tt>MetaContactChatTransport</tt> by specifying the parent
   * <tt>chatSession</tt> and the <tt>contact</tt> associated with the transport.
   *
   * @param chatSession the parent <tt>ChatSession</tt>
   * @param contact the <tt>Contact</tt> associated with this transport
   * @param contactResource the <tt>ContactResource</tt> associated with the contact
   * @param isDisplayResourceOnly indicates if only the resource name should be displayed
   */
  public MetaContactChatTransport(
      MetaContactChatSession chatSession,
      Contact contact,
      ContactResource contactResource,
      boolean isDisplayResourceOnly) {
    this.parentChatSession = chatSession;
    this.contact = contact;
    this.contactResource = contactResource;
    this.isDisplayResourceOnly = isDisplayResourceOnly;

    presenceOpSet = contact.getProtocolProvider().getOperationSet(OperationSetPresence.class);

    if (presenceOpSet != null) presenceOpSet.addContactPresenceStatusListener(this);

    // checking this can be slow so make
    // sure its out of our way
    new Thread(
            new Runnable() {
              public void run() {
                checkImCaps();
              }
            })
        .start();
  }
Example #19
0
 /**
  * Returns the <tt>ProtocolProviderService</tt>, corresponding to this chat transport.
  *
  * @return the <tt>ProtocolProviderService</tt>, corresponding to this chat transport.
  */
 public ProtocolProviderService getProtocolProvider() {
   return contact.getProtocolProvider();
 }
Example #20
0
  /**
   * Returns <code>true</code> if this chat transport supports file transfer, otherwise returns
   * <code>false</code>.
   *
   * @return <code>true</code> if this chat transport supports file transfer, otherwise returns
   *     <code>false</code>.
   */
  public boolean allowsFileTransfer() {
    Object ftOpSet = contact.getProtocolProvider().getOperationSet(OperationSetFileTransfer.class);

    if (ftOpSet != null) return true;
    else return false;
  }
Example #21
0
  /**
   * Loads the tooltip with the data for current metacontact.
   *
   * @param tip the tooltip to fill.
   */
  private void loadTooltip(final ExtendedTooltip tip) {
    Iterator<Contact> i = metaContact.getContacts();

    ContactPhoneUtil contactPhoneUtil = ContactPhoneUtil.getPhoneUtil(metaContact);

    String statusMessage = null;
    Contact protocolContact;
    boolean isLoading = false;
    while (i.hasNext()) {
      protocolContact = i.next();

      // Set the first found status message.
      if (statusMessage == null
          && protocolContact.getStatusMessage() != null
          && protocolContact.getStatusMessage().length() > 0)
        statusMessage = protocolContact.getStatusMessage();

      if (ConfigurationUtils.isHideAccountStatusSelectorsEnabled()) break;

      ImageIcon protocolStatusIcon =
          ImageLoader.getIndexedProtocolIcon(
              ImageUtils.getBytesInImage(protocolContact.getPresenceStatus().getStatusIcon()),
              protocolContact.getProtocolProvider());

      String contactAddress = protocolContact.getAddress();
      // String statusMessage = protocolContact.getStatusMessage();

      tip.addLine(protocolStatusIcon, contactAddress);

      addContactResourceTooltipLines(tip, protocolContact);

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

      contactPhoneUtil.addDetailsResponseListener(
          protocolContact,
          new OperationSetServerStoredContactInfo.DetailsResponseListener() {
            public void detailsRetrieved(final Iterator<GenericDetail> details) {
              if (!SwingUtilities.isEventDispatchThread()) {
                SwingUtilities.invokeLater(
                    new Runnable() {
                      public void run() {
                        detailsRetrieved(details);
                      }
                    });
                return;
              }

              // remove previously shown information
              // as it contains "Loading..." text
              tip.removeAllLines();

              // load it again
              loadTooltip(tip);
            }
          });

      List<String> phones = contactPhoneUtil.getPhones(protocolContact);

      if (phones != null) {
        addPhoneTooltipLines(tip, phones.iterator());
      } else isLoading = true;
    }

    if (isLoading)
      tip.addLine(null, GuiActivator.getResources().getI18NString("service.gui.LOADING"));

    if (statusMessage != null) tip.setBottomText(statusMessage);
  }
Example #22
0
  /**
   * Returns the maximum file length supported by the protocol in bytes.
   *
   * @return the file length that is supported.
   */
  public long getMaximumFileLength() {
    OperationSetFileTransfer ftOpSet =
        contact.getProtocolProvider().getOperationSet(OperationSetFileTransfer.class);

    return ftOpSet.getMaximumFileLength();
  }
  /**
   * 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);
  }