Пример #1
0
  /**
   * Creates the buttons panel.
   *
   * @return the buttons panel
   */
  private Component createButtonsPanel() {
    JPanel buttonsPanel = new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));

    JButton okButton = new JButton(GuiActivator.getResources().getI18NString("service.gui.OK"));

    okButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            selectedDevice = (MediaDevice) deviceComboBox.getSelectedItem();

            dispose();
          }
        });

    buttonsPanel.add(okButton);

    cancelButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            selectedDevice = null;
            dispose();
          }
        });

    buttonsPanel.add(cancelButton);

    return buttonsPanel;
  }
Пример #2
0
  /** Sets the names of the call buttons depending on the chat session type. */
  private void setCallButtonsName() {
    if (chatSession instanceof ConferenceChatSession) {
      callButton.setName("createConference");
      callVideoButton.setName("createConference");
      this.callButton.setToolTipText(
          GuiActivator.getResources().getI18NString("service.gui.CREATE_JOIN_VIDEO_CONFERENCE"));

      this.callVideoButton.setToolTipText(
          GuiActivator.getResources().getI18NString("service.gui.CREATE_JOIN_VIDEO_CONFERENCE"));
    } else {
      callButton.setName("call");
      callVideoButton.setName("callVideo");
      this.callButton.setToolTipText(
          GuiActivator.getResources().getI18NString("service.gui.CALL_CONTACT"));

      this.callVideoButton.setToolTipText(
          GuiActivator.getResources().getI18NString("service.gui.CALL_CONTACT"));
    }
  }
Пример #3
0
  private void initSmiliesSelectorBox() {
    this.smileysBox = new SmileysSelectorBox();

    this.smileysBox.setName("smiley");
    this.smileysBox.setToolTipText(
        GuiActivator.getResources().getI18NString("service.gui.INSERT_SMILEY") + " Ctrl-M");

    SIPCommMenuBar smileyMenuBar = new SIPCommMenuBar();
    smileyMenuBar.setOpaque(false);
    smileyMenuBar.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
    smileyMenuBar.add(smileysBox);

    this.add(smileyMenuBar);
  }
Пример #4
0
  /**
   * Creates an instance of <tt>ShowPreviewDialog</tt>
   *
   * @param chatPanel The <tt>ChatConversationPanel</tt> that is associated with this dialog.
   */
  ShowPreviewDialog(final ChatConversationPanel chatPanel) {
    this.chatPanel = chatPanel;

    this.setTitle(
        GuiActivator.getResources().getI18NString("service.gui.SHOW_PREVIEW_DIALOG_TITLE"));
    okButton = new JButton(GuiActivator.getResources().getI18NString("service.gui.OK"));
    cancelButton = new JButton(GuiActivator.getResources().getI18NString("service.gui.CANCEL"));

    JPanel mainPanel = new TransparentPanel();
    mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
    mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
    // mainPanel.setPreferredSize(new Dimension(200, 150));
    this.getContentPane().add(mainPanel);

    JTextPane descriptionMsg = new JTextPane();
    descriptionMsg.setEditable(false);
    descriptionMsg.setOpaque(false);
    descriptionMsg.setText(
        GuiActivator.getResources().getI18NString("service.gui.SHOW_PREVIEW_WARNING_DESCRIPTION"));

    Icon warningIcon = null;
    try {
      warningIcon =
          new ImageIcon(
              ImageIO.read(
                  GuiActivator.getResources().getImageURL("service.gui.icons.WARNING_ICON")));
    } catch (IOException e) {
      logger.debug("failed to load the warning icon");
    }
    JLabel warningSign = new JLabel(warningIcon);

    JPanel warningPanel = new TransparentPanel();
    warningPanel.setLayout(new BoxLayout(warningPanel, BoxLayout.X_AXIS));
    warningPanel.add(warningSign);
    warningPanel.add(Box.createHorizontalStrut(10));
    warningPanel.add(descriptionMsg);

    enableReplacement =
        new JCheckBox(
            GuiActivator.getResources()
                .getI18NString("plugin.chatconfig.replacement.ENABLE_REPLACEMENT_STATUS"));
    enableReplacement.setOpaque(false);
    enableReplacement.setSelected(cfg.getBoolean(ReplacementProperty.REPLACEMENT_ENABLE, true));
    enableReplacementProposal =
        new JCheckBox(
            GuiActivator.getResources()
                .getI18NString("plugin.chatconfig.replacement.ENABLE_REPLACEMENT_PROPOSAL"));
    enableReplacementProposal.setOpaque(false);

    JPanel checkBoxPanel = new TransparentPanel();
    checkBoxPanel.setLayout(new BoxLayout(checkBoxPanel, BoxLayout.Y_AXIS));
    checkBoxPanel.add(enableReplacement);
    checkBoxPanel.add(enableReplacementProposal);

    JPanel buttonsPanel = new TransparentPanel(new FlowLayout(FlowLayout.CENTER));
    buttonsPanel.add(okButton);
    buttonsPanel.add(cancelButton);

    mainPanel.add(warningPanel);
    mainPanel.add(Box.createVerticalStrut(10));
    mainPanel.add(checkBoxPanel);
    mainPanel.add(buttonsPanel);

    okButton.addActionListener(this);
    cancelButton.addActionListener(this);

    this.setPreferredSize(new Dimension(390, 230));
  }
Пример #5
0
  /** Initializes this component. */
  protected void init() {
    this.setLayout(new FlowLayout(FlowLayout.LEFT, 3, 0));
    this.setOpaque(false);

    this.add(inviteButton);

    // if we leave a chat room when we close the window
    // there is no need for this button
    if (!ConfigurationUtils.isLeaveChatRoomOnWindowCloseEnabled()) this.add(leaveChatRoomButton);

    this.add(callButton);
    this.add(callVideoButton);
    this.add(desktopSharingButton);
    this.add(sendFileButton);

    ChatPanel chatPanel = chatContainer.getCurrentChat();
    if (chatPanel == null || !(chatPanel.getChatSession() instanceof MetaContactChatSession))
      sendFileButton.setEnabled(false);

    this.addSeparator();

    this.add(historyButton);
    this.add(previousButton);
    this.add(nextButton);

    // We only add the options button if the property SHOW_OPTIONS_WINDOW
    // specifies so or if it's not set.
    Boolean showOptionsProp =
        GuiActivator.getConfigurationService()
            .getBoolean(ConfigurationFrame.SHOW_OPTIONS_WINDOW_PROPERTY, false);

    if (showOptionsProp.booleanValue()) {
      this.add(optionsButton);
    }

    this.addSeparator();

    if (ConfigurationUtils.isFontSupportEnabled()) {
      this.add(fontButton);
      fontButton.setName("font");
      fontButton.setToolTipText(
          GuiActivator.getResources().getI18NString("service.gui.CHANGE_FONT"));
      fontButton.addActionListener(this);
    }

    initSmiliesSelectorBox();

    this.addSeparator();

    this.inviteButton.setName("invite");
    this.inviteButton.setToolTipText(
        GuiActivator.getResources().getI18NString("service.gui.INVITE"));

    this.leaveChatRoomButton.setName("leave");
    this.leaveChatRoomButton.setToolTipText(
        GuiActivator.getResources().getI18NString("service.gui.LEAVE"));

    this.callButton.setName("call");
    this.callButton.setToolTipText(
        GuiActivator.getResources().getI18NString("service.gui.CALL_CONTACT"));

    this.callVideoButton.setName("callVideo");
    this.callVideoButton.setToolTipText(
        GuiActivator.getResources().getI18NString("service.gui.CALL_CONTACT"));

    this.desktopSharingButton.setName("desktop");
    this.desktopSharingButton.setToolTipText(
        GuiActivator.getResources().getI18NString("service.gui.SHARE_DESKTOP_WITH_CONTACT"));

    this.historyButton.setName("history");
    this.historyButton.setToolTipText(
        GuiActivator.getResources().getI18NString("service.gui.HISTORY") + " Ctrl-H");

    optionsButton.setName("options");
    optionsButton.setToolTipText(GuiActivator.getResources().getI18NString("service.gui.OPTIONS"));

    this.sendFileButton.setName("sendFile");
    this.sendFileButton.setToolTipText(
        GuiActivator.getResources().getI18NString("service.gui.SEND_FILE"));

    this.previousButton.setName("previous");
    this.previousButton.setToolTipText(
        GuiActivator.getResources().getI18NString("service.gui.PREVIOUS"));

    this.nextButton.setName("next");
    this.nextButton.setToolTipText(GuiActivator.getResources().getI18NString("service.gui.NEXT"));

    inviteButton.addActionListener(this);
    leaveChatRoomButton.addActionListener(this);
    callButton.addActionListener(this);
    callVideoButton.addActionListener(this);
    desktopSharingButton.addActionListener(this);
    historyButton.addActionListener(this);
    optionsButton.addActionListener(this);
    sendFileButton.addActionListener(this);
    previousButton.addActionListener(this);
    nextButton.addActionListener(this);
  }
Пример #6
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;
  }
}
  /** Creates a file conversation component. */
  public FileTransferConversationComponent() {
    imageLabel = new FileImageLabel();

    constraints.gridx = 0;
    constraints.gridy = 0;
    constraints.gridwidth = 1;
    constraints.gridheight = 4;
    constraints.anchor = GridBagConstraints.NORTHWEST;
    constraints.insets = new Insets(5, 5, 5, 5);

    add(imageLabel, constraints);
    imageLabel.setIcon(new ImageIcon(ImageLoader.getImage(ImageLoader.DEFAULT_FILE_ICON)));

    constraints.gridx = 1;
    constraints.gridy = 0;
    constraints.gridwidth = 3;
    constraints.gridheight = 1;
    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.weightx = 1.0;
    constraints.anchor = GridBagConstraints.NORTHWEST;
    constraints.insets = new Insets(5, 5, 5, 5);

    add(titleLabel, constraints);
    titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 11f));

    constraints.gridx = 1;
    constraints.gridy = 1;
    constraints.anchor = GridBagConstraints.WEST;
    constraints.insets = new Insets(0, 5, 5, 5);

    add(fileLabel, constraints);

    constraints.gridx = 1;
    constraints.gridy = 2;
    constraints.gridwidth = 1;
    constraints.anchor = GridBagConstraints.WEST;
    constraints.insets = new Insets(0, 5, 0, 5);
    constraints.fill = GridBagConstraints.NONE;

    add(errorIconLabel, constraints);
    errorIconLabel.setVisible(false);

    constraints.gridx = 2;
    constraints.gridy = 2;
    constraints.gridwidth = 2;
    constraints.anchor = GridBagConstraints.WEST;
    constraints.insets = new Insets(0, 5, 0, 5);
    constraints.fill = GridBagConstraints.HORIZONTAL;

    add(errorArea, constraints);
    errorArea.setForeground(new Color(resources.getColor("service.gui.ERROR_FOREGROUND")));
    setTextAreaStyle(errorArea);
    errorArea.setVisible(false);

    constraints.gridx = 1;
    constraints.gridy = 3;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0.0;
    constraints.anchor = GridBagConstraints.WEST;
    constraints.insets = new Insets(0, 5, 0, 5);

    add(retryButton, constraints);
    retryButton.setText(GuiActivator.getResources().getI18NString("service.gui.RETRY"));
    retryButton.setVisible(false);

    constraints.gridx = 1;
    constraints.gridy = 3;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0.0;
    constraints.anchor = GridBagConstraints.WEST;
    constraints.insets = new Insets(0, 5, 0, 5);

    add(cancelButton, constraints);
    cancelButton.setText(GuiActivator.getResources().getI18NString("service.gui.CANCEL"));
    cancelButton.addActionListener(this);
    cancelButton.setVisible(false);

    constraints.gridx = 2;
    constraints.gridy = 3;
    constraints.gridwidth = GridBagConstraints.RELATIVE;
    constraints.gridheight = 1;
    constraints.weightx = 0.0;
    constraints.fill = GridBagConstraints.NONE;
    constraints.anchor = GridBagConstraints.EAST;
    constraints.insets = new Insets(0, 5, 0, 5);

    constraints.gridx = 3;
    constraints.gridy = 3;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0.0;
    constraints.fill = GridBagConstraints.NONE;
    constraints.anchor = GridBagConstraints.LINE_END;
    constraints.insets = new Insets(0, 5, 0, 5);

    add(progressPropertiesPanel, constraints);

    estimatedTimeLabel.setFont(estimatedTimeLabel.getFont().deriveFont(11f));
    estimatedTimeLabel.setVisible(false);
    progressSpeedLabel.setFont(progressSpeedLabel.getFont().deriveFont(11f));
    progressSpeedLabel.setVisible(false);

    progressPropertiesPanel.add(progressSpeedLabel);
    progressPropertiesPanel.add(estimatedTimeLabel);

    constraints.gridx = 1;
    constraints.gridy = 3;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0.0;
    constraints.anchor = GridBagConstraints.WEST;
    constraints.insets = new Insets(0, 5, 0, 5);
    constraints.fill = GridBagConstraints.NONE;

    add(acceptButton, constraints);
    acceptButton.setText(GuiActivator.getResources().getI18NString("service.gui.ACCEPT"));
    acceptButton.setVisible(false);

    constraints.gridx = 2;
    constraints.gridy = 3;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0.0;
    constraints.anchor = GridBagConstraints.WEST;
    constraints.insets = new Insets(0, 5, 0, 5);
    constraints.fill = GridBagConstraints.NONE;

    add(rejectButton, constraints);
    rejectButton.setText(GuiActivator.getResources().getI18NString("service.gui.REJECT"));
    rejectButton.setVisible(false);

    constraints.gridx = 1;
    constraints.gridy = 3;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0.0;
    constraints.anchor = GridBagConstraints.WEST;
    constraints.insets = new Insets(0, 5, 0, 5);
    constraints.fill = GridBagConstraints.NONE;

    add(openFileButton, constraints);
    openFileButton.setText(GuiActivator.getResources().getI18NString("service.gui.OPEN"));
    openFileButton.setVisible(false);
    openFileButton.addActionListener(this);

    constraints.gridx = 2;
    constraints.gridy = 3;
    constraints.gridwidth = 1;
    constraints.gridheight = 1;
    constraints.weightx = 0.0;
    constraints.anchor = GridBagConstraints.WEST;
    constraints.insets = new Insets(0, 5, 0, 5);
    constraints.fill = GridBagConstraints.NONE;

    add(openFolderButton, constraints);
    openFolderButton.setText(GuiActivator.getResources().getI18NString("service.gui.OPEN_FOLDER"));
    openFolderButton.setVisible(false);
    openFolderButton.addActionListener(this);

    constraints.gridx = 1;
    constraints.gridy = 2;
    constraints.gridwidth = 3;
    constraints.gridheight = 1;
    constraints.weightx = 1.0;
    constraints.anchor = GridBagConstraints.WEST;
    constraints.insets = new Insets(0, 5, 0, 5);
    constraints.ipadx = 150;
    constraints.fill = GridBagConstraints.HORIZONTAL;

    add(progressBar, constraints);
    progressBar.setVisible(false);
    progressBar.setStringPainted(true);
  }
Пример #8
0
/**
 * A dialog dedicated to desktop streaming/sharing. Shows the possible screens to select from to use
 * for the streaming/sharing session.
 *
 * @author Yana Stamcheva
 */
public class SelectScreenDialog extends SIPCommDialog {
  /** Serial version UID. */
  private static final long serialVersionUID = 0L;

  /** The object used for logging. */
  private static final Logger logger = Logger.getLogger(SelectScreenDialog.class);

  /** The combo box containing screen choice. */
  private final JComboBox deviceComboBox;

  /** The cancel button of this dialog. */
  private final JButton cancelButton =
      new JButton(GuiActivator.getResources().getI18NString("service.gui.CANCEL"));

  /**
   * The video <code>CaptureDeviceInfo</code> this instance started to create the preview of.
   *
   * <p>Because the creation of the preview is asynchronous, it's possible to request the preview of
   * one and the same device multiple times. Which may lead to failures because of, for example,
   * busy devices and/or resources (as is the case with LTI-CIVIL and video4linux2).
   */
  private static MediaDevice videoDeviceInPreview;

  /** The selected media device. */
  private MediaDevice selectedDevice;

  /**
   * Creates an instance of <tt>SelectScreenDialog</tt> by specifying the list of possible desktop
   * devices to choose from.
   *
   * @param desktopDevices the list of possible desktop devices to choose from
   */
  public SelectScreenDialog(List<MediaDevice> desktopDevices) {
    setModal(true);

    setPreferredSize(new Dimension(400, 300));

    Container contentPane = getContentPane();
    contentPane.setLayout(new BorderLayout());

    deviceComboBox = new JComboBox(desktopDevices.toArray());
    contentPane.add(deviceComboBox, BorderLayout.NORTH);

    deviceComboBox.setRenderer(new ComboRenderer());

    contentPane.add(createPreview(deviceComboBox));

    contentPane.add(createButtonsPanel(), BorderLayout.SOUTH);
  }

  /**
   * Returns the selected device.
   *
   * @return the selected device
   */
  public MediaDevice getSelectedDevice() {
    return selectedDevice;
  }

  /**
   * Creates the buttons panel.
   *
   * @return the buttons panel
   */
  private Component createButtonsPanel() {
    JPanel buttonsPanel = new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));

    JButton okButton = new JButton(GuiActivator.getResources().getI18NString("service.gui.OK"));

    okButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            selectedDevice = (MediaDevice) deviceComboBox.getSelectedItem();

            dispose();
          }
        });

    buttonsPanel.add(okButton);

    cancelButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            selectedDevice = null;
            dispose();
          }
        });

    buttonsPanel.add(cancelButton);

    return buttonsPanel;
  }

  /**
   * Create preview component.
   *
   * @param comboBox the options.
   * @return the component.
   */
  private static Component createPreview(final JComboBox comboBox) {
    final JComponent preview;

    JLabel noPreview =
        new JLabel(GuiActivator.getResources().getI18NString("impl.media.configform.NO_PREVIEW"));
    noPreview.setHorizontalAlignment(SwingConstants.CENTER);
    noPreview.setVerticalAlignment(SwingConstants.CENTER);

    preview = createVideoContainer(noPreview);

    preview.setPreferredSize(new Dimension(WIDTH, 280));
    preview.setMaximumSize(new Dimension(WIDTH, 280));

    final ActionListener comboBoxListener =
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            MediaDevice device = (MediaDevice) comboBox.getSelectedItem();

            if ((device != null) && device.equals(videoDeviceInPreview)) return;

            Exception exception;
            try {
              createPreview(device, preview);
              exception = null;
            } catch (IOException ex) {
              exception = ex;
            } catch (MediaException ex) {
              exception = ex;
            }
            if (exception != null) {
              logger.error("Failed to create preview for device " + device, exception);

              device = null;
            }

            videoDeviceInPreview = device;
          }
        };
    comboBox.addActionListener(comboBoxListener);

    /*
     * We have to initialize the controls to reflect the configuration
     * at the time of creating this instance. Additionally, because the
     * video preview will stop when it and its associated controls
     * become unnecessary, we have to restart it when the mentioned
     * controls become necessary again. We'll address the two goals
     * described by pretending there's a selection in the video combo
     * box when the combo box in question becomes displayable.
     */
    comboBox.addHierarchyListener(
        new HierarchyListener() {
          public void hierarchyChanged(HierarchyEvent event) {
            if (((event.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0)
                && comboBox.isDisplayable()) {
              // let current changes end their execution
              // and after that trigger action on combobox
              SwingUtilities.invokeLater(
                  new Runnable() {
                    public void run() {
                      comboBoxListener.actionPerformed(null);
                    }
                  });
            } else {
              if (!comboBox.isDisplayable()) videoDeviceInPreview = null;
            }
          }
        });

    return preview;
  }

  /**
   * Creates preview for the device(video) in the video container.
   *
   * @param device the device
   * @param videoContainer the container
   * @throws IOException a problem accessing the device.
   * @throws MediaException a problem getting preview.
   */
  private static void createPreview(MediaDevice device, final JComponent videoContainer)
      throws IOException, MediaException {
    videoContainer.removeAll();

    videoContainer.revalidate();
    videoContainer.repaint();

    if (device == null) return;

    Component c =
        (Component)
            GuiActivator.getMediaService()
                .getVideoPreviewComponent(
                    device, videoContainer.getSize().width, videoContainer.getSize().height);

    videoContainer.add(c);
  }

  /**
   * Creates the video container.
   *
   * @param noVideoComponent the container component.
   * @return the video container.
   */
  private static JComponent createVideoContainer(Component noVideoComponent) {
    return new VideoContainer(noVideoComponent, false);
  }

  /** Custom combo box renderer. */
  private static class ComboRenderer extends DefaultListCellRenderer {
    @Override
    public Component getListCellRendererComponent(
        JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
      super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

      MediaDevice mediaDevice = (MediaDevice) value;

      Dimension screenSize = null;
      if (mediaDevice != null) screenSize = ((VideoMediaFormat) mediaDevice.getFormat()).getSize();

      this.setText(screenSize.width + "x" + screenSize.height);

      return this;
    }
  }

  /**
   * Automatically press the cancel button when this dialog has been escaped.
   *
   * @param escaped indicates if this dialog has been closed by pressing the ESC key
   */
  @Override
  protected void close(boolean escaped) {
    if (escaped) cancelButton.doClick();
  }
}
Пример #9
0
  /**
   * Create preview component.
   *
   * @param comboBox the options.
   * @return the component.
   */
  private static Component createPreview(final JComboBox comboBox) {
    final JComponent preview;

    JLabel noPreview =
        new JLabel(GuiActivator.getResources().getI18NString("impl.media.configform.NO_PREVIEW"));
    noPreview.setHorizontalAlignment(SwingConstants.CENTER);
    noPreview.setVerticalAlignment(SwingConstants.CENTER);

    preview = createVideoContainer(noPreview);

    preview.setPreferredSize(new Dimension(WIDTH, 280));
    preview.setMaximumSize(new Dimension(WIDTH, 280));

    final ActionListener comboBoxListener =
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            MediaDevice device = (MediaDevice) comboBox.getSelectedItem();

            if ((device != null) && device.equals(videoDeviceInPreview)) return;

            Exception exception;
            try {
              createPreview(device, preview);
              exception = null;
            } catch (IOException ex) {
              exception = ex;
            } catch (MediaException ex) {
              exception = ex;
            }
            if (exception != null) {
              logger.error("Failed to create preview for device " + device, exception);

              device = null;
            }

            videoDeviceInPreview = device;
          }
        };
    comboBox.addActionListener(comboBoxListener);

    /*
     * We have to initialize the controls to reflect the configuration
     * at the time of creating this instance. Additionally, because the
     * video preview will stop when it and its associated controls
     * become unnecessary, we have to restart it when the mentioned
     * controls become necessary again. We'll address the two goals
     * described by pretending there's a selection in the video combo
     * box when the combo box in question becomes displayable.
     */
    comboBox.addHierarchyListener(
        new HierarchyListener() {
          public void hierarchyChanged(HierarchyEvent event) {
            if (((event.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0)
                && comboBox.isDisplayable()) {
              // let current changes end their execution
              // and after that trigger action on combobox
              SwingUtilities.invokeLater(
                  new Runnable() {
                    public void run() {
                      comboBoxListener.actionPerformed(null);
                    }
                  });
            } else {
              if (!comboBox.isDisplayable()) videoDeviceInPreview = null;
            }
          }
        });

    return preview;
  }