private String getNickname() {
    String nickName = null;
    ChatOperationReasonDialog reasonDialog =
        new ChatOperationReasonDialog(
            GuiActivator.getResources().getI18NString("service.gui.CHANGE_NICKNAME"),
            GuiActivator.getResources().getI18NString("service.gui.CHANGE_NICKNAME_LABEL"));

    reasonDialog.setReasonFieldText("");

    int result = reasonDialog.showDialog();

    if (result == MessageDialog.OK_RETURN_CODE) {
      nickName = reasonDialog.getReason().trim();
    }

    return nickName;
  }
  /**
   * Creates a new <tt>JMenuItem</tt> and adds it to this <tt>JPopupMenu</tt>.
   *
   * @param textKey the key of the internationalized string in the resources of the application
   *     which represents the text of the new <tt>JMenuItem</tt>
   * @param iconID the <tt>ImageID</tt> of the image in the resources of the application which
   *     represents the icon of the new <tt>JMenuItem</tt>
   * @param name the name of the new <tt>JMenuItem</tt>
   * @return a new <tt>JMenuItem</tt> instance which has been added to this <tt>JPopupMenu</tt>
   */
  private JMenuItem createMenuItem(String textKey, ImageID iconID, String name) {
    ResourceManagementService resources = GuiActivator.getResources();
    JMenuItem menuItem =
        new JMenuItem(
            resources.getI18NString(textKey), new ImageIcon(ImageLoader.getImage(iconID)));

    menuItem.setMnemonic(resources.getI18nMnemonic(textKey));
    menuItem.setName(name);

    menuItem.addActionListener(this);

    add(menuItem);

    return menuItem;
  }
Beispiel #3
0
  /**
   * Creates a full filename for the call by combining the directory, file prefix and extension. If
   * the directory is <tt>null</tt> user's home directory is used.
   *
   * @param savedCallsPath the path to the directory in which the generated file name is to be
   *     placed
   * @return a full filename for the call
   */
  private String createDefaultFilename(String savedCallsPath) {
    // set to user's home when null
    if (savedCallsPath == null) {
      try {
        savedCallsPath =
            GuiActivator.getFileAccessService().getDefaultDownloadDirectory().getAbsolutePath();
      } catch (IOException ioex) {
        // Leave it in the current directory.
      }
    }

    String ext = configuration.getString(Recorder.FORMAT);

    // Use a default format when the configured one seems invalid.
    if ((ext == null) || (ext.length() == 0) || !isSupportedFormat(ext))
      ext = SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;
    return ((savedCallsPath == null) ? "" : (savedCallsPath + File.separator))
        + generateCallFilename(ext);
  }
Beispiel #4
0
/**
 * The button that starts/stops the call recording.
 *
 * @author Dmitri Melnikov
 * @author Lubomir Marinov
 */
public class RecordButton extends AbstractCallToggleButton {
  /** The logger used by the <tt>RecordButton</tt> class and its instances for logging output. */
  private static final Logger logger = Logger.getLogger(RecordButton.class);

  /** The date format used in file names. */
  private static final SimpleDateFormat FORMAT = new SimpleDateFormat("*****@*****.**");

  /** Configuration service. */
  private static final ConfigurationService configuration = GuiActivator.getConfigurationService();

  /** Resource service. */
  private static final ResourceManagementService resources = GuiActivator.getResources();

  /** Maximum allowed file name length. */
  private static final int MAX_FILENAME_LENGTH = 64;

  /** The full filename of the saved call on the file system. */
  private String callFilename;

  /** Call file chooser. */
  private SipCommFileChooser callFileChooser;

  /**
   * The <tt>Recorder</tt> which is depicted by this <tt>RecordButton</tt> and which is to record or
   * records {@link #call} into {@link #callFilename}.
   */
  private Recorder recorder;

  /**
   * Initializes a new <tt>RecordButton</tt> instance which is to record the audio stream.
   *
   * @param call the <tt>Call</tt> to be associated with the new instance and to have the audio
   *     stream recorded
   */
  public RecordButton(Call call) {
    this(call, false);
  }

  /**
   * Initializes a new <tt>RecordButton</tt> instance which is to record the audio stream.
   *
   * @param call the <tt>Call</tt> to be associated with the new instance and to have its audio
   *     stream recorded
   * @param selected <tt>true</tt> if the new toggle button is to be initially selected; otherwise,
   *     <tt>false</tt>
   */
  public RecordButton(Call call, boolean selected) {
    super(call, true, selected, ImageLoader.RECORD_BUTTON, ImageLoader.RECORD_BUTTON_PRESSED, null);

    String toolTip = resources.getI18NString("service.gui.RECORD_BUTTON_TOOL_TIP");
    String saveDir = configuration.getString(Recorder.SAVED_CALLS_PATH);

    if ((saveDir != null) && (saveDir.length() != 0)) toolTip += " (" + saveDir + ")";
    setToolTipText(toolTip);
  }

  /** Starts/stops the recording of the call when this button is pressed. */
  @Override
  public void buttonPressed() {
    if (call != null) {
      // start recording
      if (isSelected()) {
        boolean startedRecording = false;

        try {
          startedRecording = startRecording();
        } finally {
          if (!startedRecording && (recorder != null)) {
            try {
              recorder.stop();
            } finally {
              recorder = null;
            }
          }
          setSelected(startedRecording);
        }
      }
      // stop recording
      else if (recorder != null) {
        try {
          recorder.stop();
        } finally {
          recorder = null;
          setSelected(false);
        }
      }
    }
  }

  /**
   * Creates a full filename for the call by combining the directory, file prefix and extension. If
   * the directory is <tt>null</tt> user's home directory is used.
   *
   * @param savedCallsPath the path to the directory in which the generated file name is to be
   *     placed
   * @return a full filename for the call
   */
  private String createDefaultFilename(String savedCallsPath) {
    // set to user's home when null
    if (savedCallsPath == null) {
      try {
        savedCallsPath =
            GuiActivator.getFileAccessService().getDefaultDownloadDirectory().getAbsolutePath();
      } catch (IOException ioex) {
        // Leave it in the current directory.
      }
    }

    String ext = configuration.getString(Recorder.FORMAT);

    // Use a default format when the configured one seems invalid.
    if ((ext == null) || (ext.length() == 0) || !isSupportedFormat(ext))
      ext = SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;
    return ((savedCallsPath == null) ? "" : (savedCallsPath + File.separator))
        + generateCallFilename(ext);
  }

  /**
   * Generates a file name for the call based on the current date and the names of the peers in the
   * call.
   *
   * @param ext file extension
   * @return the file name for the call
   */
  private String generateCallFilename(String ext) {
    String filename = FORMAT.format(new Date()) + "-call";
    int maxLength = MAX_FILENAME_LENGTH - 2 - filename.length() - ext.length();
    String peerName = getCallPeerName(maxLength);
    filename += ((!peerName.equals("")) ? "-" : "") + peerName + "." + ext;
    return filename;
  }

  /**
   * Gets and formats the names of the peers in the call.
   *
   * @param maxLength maximum length of the filename
   * @return the name of the peer in the call formated
   */
  private String getCallPeerName(int maxLength) {
    List<CallPeer> callPeers = call.getConference().getCallPeers();
    CallPeer callPeer = null;
    String peerName = "";
    if (!callPeers.isEmpty()) {
      callPeer = callPeers.get(0);
      if (callPeer != null) {
        peerName = callPeer.getDisplayName();
        peerName = peerName.replaceAll("[^\\da-zA-Z\\_\\-@\\.]", "");
        if (peerName.length() > maxLength) {
          peerName = peerName.substring(0, maxLength);
        }
      }
    }
    return peerName;
  }

  /**
   * Gets the <tt>Recorder</tt> represented by this <tt>RecordButton</tt> creating it first if it
   * does not exist.
   *
   * @return the <tt>Recorder</tt> represented by this <tt>RecordButton</tt> created first if it
   *     does not exist
   * @throws OperationFailedException if anything goes wrong while creating the <tt>Recorder</tt> to
   *     be represented by this <tt>RecordButton</tt>
   */
  private Recorder getRecorder() throws OperationFailedException {
    if (recorder == null) {
      OperationSetBasicTelephony<?> telephony =
          call.getProtocolProvider().getOperationSet(OperationSetBasicTelephony.class);

      recorder = telephony.createRecorder(call);
    }
    return recorder;
  }

  /**
   * Determines whether the extension of a specific <tt>File</tt> specifies a format supported by
   * the <tt>Recorder</tt> represented by this <tt>RecordButton</tt>.
   *
   * @param file the <tt>File</tt> whose extension is to be checked whether it specifies a format
   *     supported by the <tt>Recorder</tt> represented by this <tt>RecordButton</tt>
   * @return <tt>true</tt> if the extension of the specified <tt>file</tt> specifies a format
   *     supported by the <tt>Recorder</tt> represented by this <tt>RecordButton</tt>; otherwise,
   *     <tt>false</tt>
   */
  private boolean isSupportedFormat(File file) {
    String extension = SoundFileUtils.getExtension(file);

    return (extension != null) && (extension.length() != 0) && isSupportedFormat(extension);
  }

  /**
   * Determines whether a specific format is supported by the <tt>Recorder</tt> represented by this
   * <tt>RecordButton</tt>.
   *
   * @param format the format which is to be checked whether it is supported by the
   *     <tt>Recorder</tt> represented by this <tt>RecordButton</tt>
   * @return <tt>true</tt> if the specified <tt>format</tt> is supported by the <tt>Recorder</tt>
   *     represented by this <tt>RecordButton</tt>; otherwise, <tt>false</tt>
   */
  private boolean isSupportedFormat(String format) {
    Recorder recorder;

    try {
      recorder = getRecorder();
    } catch (OperationFailedException ofex) {
      logger.error("Failed to get Recorder", ofex);
      return false;
    }

    List<String> supportedFormats = recorder.getSupportedFormats();

    return (supportedFormats != null) && supportedFormats.contains(format);
  }

  /**
   * Starts recording {@link #call} creating {@link #recorder} first and asking the user for the
   * recording format and file if they are not configured in the "Call Recording" configuration
   * form.
   *
   * @return <tt>true</tt> if the recording has been started successfully; otherwise, <tt>false</tt>
   */
  private boolean startRecording() {
    String savedCallsPath = configuration.getString(Recorder.SAVED_CALLS_PATH);
    String callFormat;

    // Ask the user where to save the call.
    if ((savedCallsPath == null) || (savedCallsPath.length() == 0)) {
      /*
       * Delay the initialization of callFileChooser in order to delay the
       * creation of the recorder.
       */
      if (callFileChooser == null) {
        callFileChooser =
            GenericFileDialog.create(
                null,
                resources.getI18NString("plugin.callrecordingconfig.SAVE_CALL"),
                SipCommFileChooser.SAVE_FILE_OPERATION);
        callFileChooser.addFilter(
            new SipCommFileFilter() {
              @Override
              public boolean accept(File f) {
                return f.isDirectory() || isSupportedFormat(f);
              }

              @Override
              public String getDescription() {
                StringBuilder description = new StringBuilder();

                description.append("Recorded call");

                Recorder recorder;

                try {
                  recorder = getRecorder();
                } catch (OperationFailedException ofex) {
                  logger.error("Failed to get Recorder", ofex);
                  recorder = null;
                }
                if (recorder != null) {
                  List<String> supportedFormats = recorder.getSupportedFormats();

                  if (supportedFormats != null) {
                    description.append(" (");

                    boolean firstSupportedFormat = true;

                    for (String supportedFormat : supportedFormats) {
                      if (firstSupportedFormat) firstSupportedFormat = false;
                      else description.append(", ");
                      description.append("*.");
                      description.append(supportedFormat);
                    }

                    description.append(')');
                  }
                }
                return description.toString();
              }
            });
      }
      // Offer a default name for the file to record into.
      callFileChooser.setStartPath(createDefaultFilename(null));

      File selectedFile = callFileChooser.getFileFromDialog();

      if (selectedFile != null) {
        callFilename = selectedFile.getAbsolutePath();

        /*
         * If the user specified no extension (which seems common on Mac
         * OS X at least) i.e. no format, then it is not obvious that we
         * have to override the set Recorder.CALL_FORMAT.
         */
        callFormat = SoundFileUtils.getExtension(selectedFile);

        if ((callFormat != null) && (callFormat.length() != 0)) {
          /*
           * If the use has specified an extension and thus a format
           * which is not supported, use a default format instead.
           */
          if (!isSupportedFormat(selectedFile)) {
            /*
             * If what appears to be an extension seems a lot like
             * an extension, then it should be somewhat safer to
             * replace it.
             */
            if (SoundFileUtils.isSoundFile(selectedFile)) {
              callFilename = callFilename.substring(0, callFilename.lastIndexOf('.'));
            }
            String configuredFormat = configuration.getString(Recorder.FORMAT);
            callFormat =
                (configuredFormat != null && configuredFormat.length() != 0)
                    ? configuredFormat
                    : SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;

            callFilename += '.' + callFormat;
          }
          configuration.setProperty(Recorder.FORMAT, callFormat);
        }
      } else {
        // user canceled the recording
        return false;
      }
    } else {
      callFilename = createDefaultFilename(savedCallsPath);
      callFormat = SoundFileUtils.getExtension(new File(callFilename));
    }

    Throwable exception = null;

    try {
      Recorder recorder = getRecorder();

      if (recorder != null) {
        if ((callFormat == null) || (callFormat.length() <= 0))
          callFormat = SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;

        recorder.start(callFormat, callFilename);
      }

      this.recorder = recorder;
    } catch (IOException ioex) {
      exception = ioex;
    } catch (MediaException mex) {
      exception = mex;
    } catch (OperationFailedException ofex) {
      exception = ofex;
    }
    if ((recorder == null) || (exception != null)) {
      logger.error(
          "Failed to start recording call " + call + " into file " + callFilename, exception);
      return false;
    } else return true;
  }
}
  /**
   * Handles the <tt>ActionEvent</tt>. Determines which menu item was selected and makes the
   * appropriate operations.
   *
   * @param e the event.
   */
  public void actionPerformed(ActionEvent e) {
    JMenuItem menuItem = (JMenuItem) e.getSource();
    String itemName = menuItem.getName();

    ConferenceChatManager conferenceManager =
        GuiActivator.getUIService().getConferenceChatManager();

    if (itemName.equals("removeChatRoom")) {
      conferenceManager.removeChatRoom(chatRoomWrapper);
    } else if (itemName.equals("leaveChatRoom")) {
      conferenceManager.leaveChatRoom(chatRoomWrapper);
    } else if (itemName.equals("joinChatRoom")) {
      String nickName = null;

      nickName =
          ConfigurationManager.getChatRoomProperty(
              chatRoomWrapper.getParentProvider().getProtocolProvider(),
              chatRoomWrapper.getChatRoomID(),
              "userNickName");
      if (nickName == null) nickName = getNickname();

      if (nickName != null) conferenceManager.joinChatRoom(chatRoomWrapper, nickName, null);
      else conferenceManager.joinChatRoom(chatRoomWrapper);
    } else if (itemName.equals("openChatRoom")) {
      if (chatRoomWrapper.getChatRoom() != null) {
        if (!chatRoomWrapper.getChatRoom().isJoined()) {
          String nickName = null;

          nickName =
              ConfigurationManager.getChatRoomProperty(
                  chatRoomWrapper.getParentProvider().getProtocolProvider(),
                  chatRoomWrapper.getChatRoomID(),
                  "userNickName");
          if (nickName == null) nickName = getNickname();

          if (nickName != null) conferenceManager.joinChatRoom(chatRoomWrapper, nickName, null);
          else conferenceManager.joinChatRoom(chatRoomWrapper);
        }
      } else {
        // this is not a server persistent room we must create it
        // and join
        chatRoomWrapper =
            GuiActivator.getUIService()
                .getConferenceChatManager()
                .createChatRoom(
                    chatRoomWrapper.getChatRoomName(),
                    chatRoomWrapper.getParentProvider().getProtocolProvider(),
                    new ArrayList<String>(),
                    "",
                    false,
                    true);

        String nickName = null;

        nickName =
            ConfigurationManager.getChatRoomProperty(
                chatRoomWrapper.getParentProvider().getProtocolProvider(),
                chatRoomWrapper.getChatRoomID(),
                "userNickName");

        if (nickName == null) nickName = getNickname();

        if (nickName != null) conferenceManager.joinChatRoom(chatRoomWrapper, nickName, null);
        else conferenceManager.joinChatRoom(chatRoomWrapper);
      }

      ChatWindowManager chatWindowManager = GuiActivator.getUIService().getChatWindowManager();
      ChatPanel chatPanel = chatWindowManager.getMultiChat(chatRoomWrapper, true);

      chatWindowManager.openChat(chatPanel, true);
    } else if (itemName.equals("joinAsChatRoom")) {
      ChatRoomAuthenticationWindow authWindow = new ChatRoomAuthenticationWindow(chatRoomWrapper);

      authWindow.setVisible(true);
    } else if (itemName.equals("nickNameChatRoom")) {
      String nickName = null;

      nickName =
          ConfigurationManager.getChatRoomProperty(
              chatRoomWrapper.getParentProvider().getProtocolProvider(),
              chatRoomWrapper.getChatRoomID(),
              "userNickName");

      ChatOperationReasonDialog reasonDialog =
          new ChatOperationReasonDialog(
              GuiActivator.getResources().getI18NString("service.gui.CHANGE_NICKNAME"),
              GuiActivator.getResources().getI18NString("service.gui.CHANGE_NICKNAME_LABEL"));

      reasonDialog.setReasonFieldText(
          nickName == null
              ? chatRoomWrapper.getParentProvider().getProtocolProvider().getAccountID().getUserID()
              : nickName);

      int result = reasonDialog.showDialog();

      if (result == MessageDialog.OK_RETURN_CODE) {
        nickName = reasonDialog.getReason().trim();
      }

      ConfigurationManager.updateChatRoomProperty(
          chatRoomWrapper.getParentProvider().getProtocolProvider(),
          chatRoomWrapper.getChatRoomID(),
          "userNickName",
          nickName);
    }
  }