Provides the UI means for SIP Communicator to initiate a call-transfer.

cusax-fix
Lyubomir Marinov 18 years ago
parent 3070baaf1c
commit b3913d79f0

@ -58,6 +58,7 @@ TEXT_UNDERLINED_ROLLOVER_BUTTON=resources/images/impl/gui/buttons/textUnderlined
DIAL_BUTTON=resources/images/impl/gui/buttons/dialButton.png
HOLD_BUTTON=resources/images/impl/gui/buttons/holdButton.png
MUTE_BUTTON=resources/images/impl/gui/buttons/muteButton.png
TRANSFER_CALL_BUTTON=resources/images/impl/gui/buttons/transferCallButton.png
INVITE_DIALOG_ICON=resources/images/impl/gui/common/inviteDialogIcon.png
SEND_SMS_ICON=resources/images/impl/gui/common/gsm.png
DIAL_BUTTON_BG=resources/images/impl/gui/buttons/dialButtonBg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

@ -327,6 +327,9 @@ subject=Subject
summary=Summary
today=Today
tools=&Tools
transferCallButton=Trans&fer
transferCallTargetLabel=&To:
transferCallTitle=Transfer Call
transparencyNotEnabled=Transparency is not supported by your current configuration.
typeYourRequest=Type your request here
uin=User identifier:

@ -1,3 +1,9 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.account;
import java.awt.*;

@ -71,12 +71,19 @@ public CallParticipantPanel(CallParticipant callParticipant)
this.stateLabel.setText(callParticipant.getState().getStateString());
Component holdButton = new HoldButton(this.callParticipant);
holdButton.setBounds(0, 74, 36, 36);
holdButton.setBounds(9, 74, 36, 36);
contactPanel.add(holdButton, new Integer(1));
Component muteButton = new MuteButton(this.callParticipant);
muteButton.setBounds(36, 74, 36, 36);
muteButton.setBounds(45, 74, 36, 36);
contactPanel.add(muteButton, new Integer(1));
Component transferCallButton = createTransferCallButton();
if (transferCallButton != null)
{
transferCallButton.setBounds(81, 74, 36, 36);
contactPanel.add(transferCallButton, new Integer(1));
}
}
/**
@ -126,6 +133,33 @@ public CallParticipantPanel(String participantName)
this.add(northPanel, BorderLayout.NORTH);
}
/**
* Creates a new <code>Component</code> representing a UI means to transfer
* the <code>Call</code> of the associated <code>callParticipant</code> or
* <tt>null</tt> if call-transfer is unsupported.
*
* @return a new <code>Component</code> representing the UI means to
* transfer the <code>Call</code> of <code>callParticipant</code> or
* <tt>null</tt> if call-transfer is unsupported
*/
private Component createTransferCallButton()
{
Call call = callParticipant.getCall();
if (call != null)
{
OperationSetAdvancedTelephony telephony =
(OperationSetAdvancedTelephony) call.getProtocolProvider()
.getOperationSet(OperationSetAdvancedTelephony.class);
if (telephony != null)
{
return new TransferCallButton(callParticipant);
}
}
return null;
}
/**
* Sets the state of the contained call participant.

@ -0,0 +1,175 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.call;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
/**
* Represents an UI means to transfer (the <code>Call</code> of) an associated
* <code>CallPariticant</code>.
*
* @author Lubomir Marinov
*/
public class TransferCallButton
extends JButton
{
private static final Logger logger =
Logger.getLogger(TransferCallButton.class);
/**
* The <code>CallParticipant</code> (whose <code>Call</code> is) to be
* transfered.
*/
private final CallParticipant callParticipant;
/**
* Initializes a new <code>TransferCallButton</code> instance which is to
* transfer (the <code>Call</code> of) a specific
* <code>CallParticipant</code>.
*
* @param callParticipant the <code>CallParticipant</code> to be associated
* with the new instance and to be transfered
*/
public TransferCallButton(CallParticipant callParticipant)
{
super(new ImageIcon(ImageLoader
.getImage(ImageLoader.TRANSFER_CALL_BUTTON)));
this.callParticipant = callParticipant;
addActionListener(new ActionListener()
{
/**
* Invoked when an action occurs.
*
* @param evt the <code>ActionEvent</code> instance containing the
* data associated with the action and the act of its
* performing
*/
public void actionPerformed(ActionEvent evt)
{
TransferCallButton.this.actionPerformed(this, evt);
}
});
}
/**
* Handles actions performed on this button on behalf of a specific
* <code>ActionListener</code>.
*
* @param listener the <code>ActionListener</code> notified about the
* performing of the action
* @param evt the <code>ActionEvent</code> containing the data associated
* with the action and the act of its performing
*/
private void actionPerformed(ActionListener listener, ActionEvent evt)
{
final Call call = callParticipant.getCall();
if (call != null)
{
OperationSetAdvancedTelephony telephony =
(OperationSetAdvancedTelephony) call.getProtocolProvider()
.getOperationSet(OperationSetAdvancedTelephony.class);
if (telephony != null)
{
final TransferCallDialog dialog =
new TransferCallDialog(getFrame());
/*
* Transferring a call works only when the call is in progress
* so close the dialog (if it's not already closed, of course)
* once the dialog ends.
*/
CallChangeListener callChangeListener = new CallChangeAdapter()
{
/*
* (non-Javadoc)
*
* @see net.java.sip.communicator.service.protocol.event.
* CallChangeAdapter
* #callStateChanged(net.java.sip.communicator
* .service.protocol.event.CallChangeEvent)
*/
public void callStateChanged(CallChangeEvent evt)
{
if (!CallState.CALL_IN_PROGRESS.equals(call
.getCallState()))
{
dialog.setVisible(false);
dialog.dispose();
}
}
};
call.addCallChangeListener(callChangeListener);
try
{
dialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
dialog.pack();
dialog.setVisible(true);
}
finally
{
call.removeCallChangeListener(callChangeListener);
}
String target = dialog.getTarget();
if ((target != null) && !target.isEmpty())
{
try
{
telephony.transfer(callParticipant, target);
}
catch (OperationFailedException ex)
{
logger.error("Failed to transfer call " + call + " to "
+ target, ex);
}
}
}
}
}
/**
* Gets the first <code>Frame</code> in the ancestor <code>Component</code>
* hierarchy of this button.
* <p>
* The located <code>Frame</code> (if any) is used as the owner of
* <code>Dialog</code>s opened by this button in order to provide natural
* <code>Frame</code> ownership.
* </p>
*
* @return the first <code>Frame</code> in the ancestor
* <code>Component</code> hierarchy of this button; <tt>null</tt>,
* if no such <code>Frame</code> was located
*/
private Frame getFrame()
{
for (Component component = this; component != null;)
{
Container container = component.getParent();
if (container instanceof Frame)
{
return (Frame) container;
}
component = container;
}
return null;
}
}

@ -0,0 +1,223 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.call;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import net.java.sip.communicator.impl.gui.customcontrols.*;
import net.java.sip.communicator.impl.gui.i18n.*;
import net.java.sip.communicator.impl.gui.lookandfeel.*;
/**
* Represents a <code>Dialog</code> which allows specifying the target contact
* address of a transfer-call operation.
*
* @author Lubomir Marinov
*/
public class TransferCallDialog
extends SIPCommDialog
{
private final JButton cancelButton;
private final JButton okButton;
/**
* The target contact address which is the result of this dialog.
*/
private String target;
private final JComboBox targetComboBox;
public TransferCallDialog(Frame owner)
{
super(owner);
setTitle(Messages.getI18NString("transferCallTitle").getText());
JPanel mainPanel = new JPanel(new BorderLayout(5, 5));
mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
getContentPane().add(mainPanel);
JPanel contentPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
mainPanel.add(contentPanel, BorderLayout.NORTH);
JLabel targetLabel =
new JLabel(Messages.getI18NString("transferCallTargetLabel")
.getText());
contentPanel.add(targetLabel);
targetComboBox = new SIPCommSmartComboBox();
targetComboBox.setUI(new SIPCommCallComboBoxUI());
contentPanel.add(targetComboBox);
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
okButton =
new JButton(Messages.getI18NString("transferCallButton").getText());
buttonPanel.add(okButton);
getRootPane().setDefaultButton(okButton);
cancelButton = new JButton(Messages.getI18NString("cancel").getText());
buttonPanel.add(cancelButton);
/*
* The UI hierarchy has been created and it's now safe to install the
* listeners to react to its actions.
*/
/*
* Enable/disable okButton (i.e. Transfer) in accord with the validity
* of the target contact address specified in targetComboBox.
*/
JTextField targetTextField =
(JTextField) targetComboBox.getEditor().getEditorComponent();
targetTextField.getDocument().addDocumentListener(
new DocumentListener()
{
/*
* (non-Javadoc)
*
* @see
* javax.swing.event.DocumentListener#changedUpdate(javax.swing
* .event.DocumentEvent)
*/
public void changedUpdate(DocumentEvent e)
{
TransferCallDialog.this.documentChanged(e);
}
/*
* (non-Javadoc)
*
* @see
* javax.swing.event.DocumentListener#insertUpdate(javax.swing
* .event.DocumentEvent)
*/
public void insertUpdate(DocumentEvent e)
{
TransferCallDialog.this.documentChanged(e);
}
/*
* (non-Javadoc)
*
* @see
* javax.swing.event.DocumentListener#removeUpdate(javax.swing
* .event.DocumentEvent)
*/
public void removeUpdate(DocumentEvent e)
{
TransferCallDialog.this.documentChanged(e);
}
});
documentChanged(null);
ActionListener actionListener = new ActionListener()
{
/**
* Invoked when an action occurs.
*
* @param evt the <code>ActionEvent</code> instance containing the
* data associated with the action and the act of its
* performing
*/
public void actionPerformed(ActionEvent evt)
{
TransferCallDialog.this.actionPerformed(this, evt);
}
};
okButton.addActionListener(actionListener);
cancelButton.addActionListener(actionListener);
}
/**
* Handles actions performed on this dialog on behalf of a specific
* <code>ActionListener</code>.
*
* @param listener the <code>ActionListener</code> notified about the
* performing of the action
* @param evt the <code>ActionEvent</code> containing the data associated
* with the action and the act of its performing
*/
private void actionPerformed(ActionListener listener, ActionEvent evt)
{
Object source = evt.getSource();
if (okButton.equals(source))
{
this.target = getValidTarget();
}
else if (cancelButton.equals(source))
{
this.target = null;
}
setVisible(false);
dispose();
}
/*
* (non-Javadoc)
*
* @see
* net.java.sip.communicator.impl.gui.customcontrols.SIPCommDialog#close
* (boolean)
*/
protected void close(boolean isEscaped)
{
cancelButton.doClick();
}
/**
* Handles changes in the <code>Document</code> associated with
* <code>targetComboBox</code> in order to dynamically enable/disable
* <code>okButton</code> in accord with the validity of the specified target
* contact address.
*
* @param e the <code>DocumentEvent</code> containing the data associated
* with the change
*/
private void documentChanged(DocumentEvent e)
{
okButton.setEnabled(getValidTarget() != null);
}
/**
* Gets the target contact address specified through this dialog or
* <tt>null</code> if this dialog was canceled.
*
* @return the target contact address specified through this dialog or
* <tt>null</code> if this dialog was canceled
*/
public String getTarget()
{
return target;
}
/**
* Gets the target contact address specified in the UI of this dialog if the
* specified value is valid or <tt>null</code> if there is no valid value
* specified in the UI of this dialog.
*
* @return the target contact address specified in the UI of this dialog if
* the specified value is valid or <tt>null</code> if there is no
* valid value specified in the UI of this dialog
*/
private String getValidTarget()
{
String target = targetComboBox.getEditor().getItem().toString().trim();
return ((target == null) || target.isEmpty()) ? null : target;
}
}

@ -408,6 +408,12 @@ public class ImageLoader {
*/
public static final ImageID MUTE_BUTTON = new ImageID("MUTE_BUTTON");
/**
* A call-transfer button icon. The icon shown in the CallParticipant panel.
*/
public static final ImageID TRANSFER_CALL_BUTTON =
new ImageID("TRANSFER_CALL_BUTTON");
/**
* The image used, when a contact has no photo specified.
*/

Loading…
Cancel
Save