mirror of https://github.com/sipwise/jitsi.git
parent
200e2e2c0a
commit
14e7f24bff
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 465 B |
@ -0,0 +1,787 @@
|
||||
package net.java.sip.communicator.plugin.accountinfo;
|
||||
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license. See terms of license at gnu.org.
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import net.java.sip.communicator.service.protocol.ServerStoredDetails.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* The right side panel of AccountDetailsDialog. Shows one tab of a summary of
|
||||
* contact information for the selected subcontact, and has an extended tab
|
||||
* listing all of the details.
|
||||
*
|
||||
* @author Yana Stamcheva
|
||||
*/
|
||||
public class AccountDetailsPanel
|
||||
extends JPanel
|
||||
{
|
||||
private Logger logger = Logger.getLogger(AccountDetailsPanel.class);
|
||||
|
||||
/**
|
||||
* The operation set giving access to the server stored account details.
|
||||
*/
|
||||
private OperationSetServerStoredAccountInfo accountInfoOpSet;
|
||||
|
||||
/**
|
||||
* The protocol provider.
|
||||
*/
|
||||
private ProtocolProviderService protocolProvider;
|
||||
|
||||
private JTextField firstNameField = new JTextField();
|
||||
|
||||
private JTextField middleNameField = new JTextField();
|
||||
|
||||
private JTextField lastNameField = new JTextField();
|
||||
|
||||
private JTextField genderField = new JTextField();
|
||||
|
||||
private JTextField ageField = new JTextField();
|
||||
|
||||
private JTextField birthdayField = new JTextField();
|
||||
|
||||
private JTextField emailField = new JTextField();
|
||||
|
||||
private JTextField phoneField = new JTextField();
|
||||
|
||||
private JLabel avatarLabel = new JLabel();
|
||||
|
||||
private JButton applyButton = new JButton(Resources.getString("apply"));
|
||||
|
||||
private JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
|
||||
|
||||
private JPanel mainPanel = new JPanel(new BorderLayout());
|
||||
|
||||
private JScrollPane mainScrollPane = new JScrollPane();
|
||||
|
||||
private boolean isDataLoaded = false;
|
||||
|
||||
private FirstNameDetail firstNameDetail;
|
||||
|
||||
private MiddleNameDetail middleNameDetail;
|
||||
|
||||
private LastNameDetail lastNameDetail;
|
||||
|
||||
private GenderDetail genderDetail;
|
||||
|
||||
private BirthDateDetail birthDateDetail;
|
||||
|
||||
private EmailAddressDetail emailDetail;
|
||||
|
||||
private PhoneNumberDetail phoneDetail;
|
||||
|
||||
private BinaryDetail avatarDetail;
|
||||
|
||||
private byte[] newAvatarImage;
|
||||
|
||||
/**
|
||||
* The last avatar file directory open.
|
||||
*/
|
||||
private File lastAvatarDir;
|
||||
|
||||
/**
|
||||
* Construct a panel containing all account details for the given protocol
|
||||
* provider.
|
||||
*
|
||||
* @param protocolProvider the protocol provider service
|
||||
*/
|
||||
public AccountDetailsPanel(ProtocolProviderService protocolProvider)
|
||||
{
|
||||
super(new BorderLayout());
|
||||
|
||||
this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
// this.setPreferredSize(new Dimension(500, 400));
|
||||
|
||||
accountInfoOpSet =
|
||||
(OperationSetServerStoredAccountInfo) protocolProvider
|
||||
.getOperationSet(OperationSetServerStoredAccountInfo.class);
|
||||
|
||||
this.protocolProvider = protocolProvider;
|
||||
|
||||
if (accountInfoOpSet == null)
|
||||
{
|
||||
initUnsupportedPanel();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.initSummaryPanel();
|
||||
|
||||
if (protocolProvider.isRegistered())
|
||||
{
|
||||
loadDetails();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initSummaryPanel()
|
||||
{
|
||||
JPanel summaryPanel = new JPanel(new BorderLayout(10, 10));
|
||||
|
||||
summaryPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
summaryPanel.setSize(this.getWidth(), this.getHeight());
|
||||
|
||||
// Create the avatar panel.
|
||||
JPanel leftPanel = new JPanel(new BorderLayout());
|
||||
JPanel avatarPanel = new JPanel(new BorderLayout());
|
||||
JButton changeAvatarButton = new JButton(Resources.getString("change"));
|
||||
JPanel changeButtonPanel
|
||||
= new JPanel(new FlowLayout(FlowLayout.CENTER));
|
||||
|
||||
changeAvatarButton.addActionListener(new ChangeAvatarActionListener());
|
||||
|
||||
avatarLabel.setIcon(Resources.getImage("defaultPersonIcon"));
|
||||
|
||||
changeButtonPanel.add(changeAvatarButton);
|
||||
|
||||
avatarPanel.add(avatarLabel, BorderLayout.CENTER);
|
||||
avatarPanel.add(changeButtonPanel, BorderLayout.SOUTH);
|
||||
|
||||
leftPanel.add(avatarPanel, BorderLayout.NORTH);
|
||||
|
||||
summaryPanel.add(leftPanel, BorderLayout.WEST);
|
||||
|
||||
// Create the summary details panel.
|
||||
JPanel detailsPanel = new JPanel(new BorderLayout(10, 10));
|
||||
detailsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
|
||||
summaryPanel.add(detailsPanel, BorderLayout.CENTER);
|
||||
|
||||
// Labels panel.
|
||||
JPanel labelsPanel = new JPanel(new GridLayout(0, 1, 5, 5));
|
||||
|
||||
labelsPanel.add(new JLabel(Resources.getString("firstNameNS")));
|
||||
// labelsPanel.add(new JLabel(Resources.getString("middleNameNS")));
|
||||
labelsPanel.add(new JLabel(Resources.getString("lastNameNS")));
|
||||
labelsPanel.add(new JLabel(Resources.getString("genderNS")));
|
||||
labelsPanel.add(new JLabel(Resources.getString("ageNS")));
|
||||
labelsPanel.add(new JLabel(Resources.getString("bdayNS")));
|
||||
labelsPanel.add(new JLabel(Resources.getString("emailNS")));
|
||||
labelsPanel.add(new JLabel(Resources.getString("phoneNS")));
|
||||
|
||||
detailsPanel.add(labelsPanel, BorderLayout.WEST);
|
||||
|
||||
// Values panel.
|
||||
JPanel valuesPanel = new JPanel(new GridLayout(0, 1, 5, 5));
|
||||
|
||||
valuesPanel.add(firstNameField);
|
||||
// valuesPanel.add(middleNameField);
|
||||
valuesPanel.add(lastNameField);
|
||||
valuesPanel.add(genderField);
|
||||
valuesPanel.add(ageField);
|
||||
valuesPanel.add(birthdayField);
|
||||
valuesPanel.add(emailField);
|
||||
valuesPanel.add(phoneField);
|
||||
|
||||
detailsPanel.add(valuesPanel, BorderLayout.CENTER);
|
||||
|
||||
this.mainScrollPane.getViewport().add(summaryPanel);
|
||||
|
||||
this.add(mainScrollPane, BorderLayout.NORTH);
|
||||
|
||||
this.applyButton.addActionListener(new SubmitActionListener());
|
||||
|
||||
this.buttonPanel.add(applyButton);
|
||||
|
||||
this.add(buttonPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads details for
|
||||
*/
|
||||
public void loadDetails()
|
||||
{
|
||||
this.loadSummaryDetails();
|
||||
this.isDataLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the panel that indicates to the user that the currently selected
|
||||
* contact does not support server stored contact info.
|
||||
*
|
||||
* @return the panel that is added and shows a message that the selected
|
||||
* sub-contact does not have the operation set for server stored
|
||||
* contact info supported.
|
||||
*/
|
||||
private void initUnsupportedPanel()
|
||||
{
|
||||
JTextArea unsupportedTextArea =
|
||||
new JTextArea(Resources.getString("notSupported"));
|
||||
|
||||
unsupportedTextArea.setEditable(false);
|
||||
unsupportedTextArea.setLineWrap(true);
|
||||
|
||||
JPanel unsupportedPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
|
||||
|
||||
unsupportedTextArea.setPreferredSize(new Dimension(200, 200));
|
||||
|
||||
unsupportedPanel.setBorder(
|
||||
BorderFactory.createEmptyBorder(50, 20, 50, 20));
|
||||
|
||||
unsupportedPanel.add(unsupportedTextArea);
|
||||
|
||||
this.add(unsupportedPanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a panel that can be added as the summary tab that displays the
|
||||
* following details: -
|
||||
* <p>
|
||||
* Avatar(Contact image) - FirstNameDetail - MiddleNameDetail -
|
||||
* LastNameDetail - BirthdateDetail (and calculate age) - GenderDetail -
|
||||
* EmailAddressDetail - PhoneNumberDetail. All other details will be* added
|
||||
* to our list of extended details.
|
||||
*
|
||||
* @return the panel that will be added as the summary tab.
|
||||
*/
|
||||
private void loadSummaryDetails()
|
||||
{
|
||||
Iterator contactDetails;
|
||||
|
||||
// Avatar details.
|
||||
contactDetails
|
||||
= accountInfoOpSet.getDetails(BinaryDetail.class);
|
||||
|
||||
byte[] avatarImage = null;
|
||||
if (contactDetails.hasNext())
|
||||
{
|
||||
avatarDetail = (BinaryDetail) contactDetails.next();
|
||||
|
||||
avatarImage = avatarDetail.getBytes();
|
||||
}
|
||||
|
||||
if (avatarImage != null && avatarImage.length > 0)
|
||||
avatarLabel.setIcon(new ImageIcon(
|
||||
getScaledImageInstance(avatarImage)));
|
||||
|
||||
// First name details.
|
||||
contactDetails =
|
||||
accountInfoOpSet.getDetails(FirstNameDetail.class);
|
||||
|
||||
String firstNameDetailString = "";
|
||||
while (contactDetails.hasNext())
|
||||
{
|
||||
firstNameDetail = (FirstNameDetail) contactDetails.next();
|
||||
|
||||
firstNameDetailString =
|
||||
firstNameDetailString + " " + firstNameDetail.getDetailValue();
|
||||
}
|
||||
|
||||
firstNameField.setText(firstNameDetailString);
|
||||
|
||||
// Middle name details.
|
||||
contactDetails =
|
||||
accountInfoOpSet.getDetails(MiddleNameDetail.class);
|
||||
|
||||
String middleNameDetailString = "";
|
||||
while (contactDetails.hasNext())
|
||||
{
|
||||
middleNameDetail = (MiddleNameDetail) contactDetails.next();
|
||||
middleNameDetailString =
|
||||
middleNameDetailString + " " + middleNameDetail.getDetailValue();
|
||||
}
|
||||
|
||||
middleNameField.setText(middleNameDetailString);
|
||||
|
||||
// Last name details.
|
||||
contactDetails =
|
||||
accountInfoOpSet.getDetails(LastNameDetail.class);
|
||||
|
||||
String lastNameDetailString = "";
|
||||
while (contactDetails.hasNext())
|
||||
{
|
||||
lastNameDetail = (LastNameDetail) contactDetails.next();
|
||||
|
||||
lastNameDetailString =
|
||||
lastNameDetailString + " " + lastNameDetail.getDetailValue();
|
||||
}
|
||||
|
||||
lastNameField.setText(lastNameDetailString);
|
||||
|
||||
// Gender details.
|
||||
contactDetails =
|
||||
accountInfoOpSet.getDetails(GenderDetail.class);
|
||||
|
||||
String genderDetailString = "";
|
||||
while (contactDetails.hasNext())
|
||||
{
|
||||
genderDetail = (GenderDetail) contactDetails.next();
|
||||
genderDetailString = genderDetailString + " "
|
||||
+ genderDetail.getDetailValue();
|
||||
}
|
||||
|
||||
genderField.setText(genderDetailString);
|
||||
|
||||
// Birthday details.
|
||||
contactDetails =
|
||||
accountInfoOpSet.getDetails(BirthDateDetail.class);
|
||||
|
||||
String birthDateDetailString = "";
|
||||
String ageDetail = "";
|
||||
if (contactDetails.hasNext())
|
||||
{
|
||||
birthDateDetail = (BirthDateDetail) contactDetails.next();
|
||||
|
||||
Calendar calendarDetail =
|
||||
(Calendar) birthDateDetail.getDetailValue();
|
||||
|
||||
Date birthDate = calendarDetail.getTime();
|
||||
DateFormat dateFormat = DateFormat.getDateInstance();
|
||||
|
||||
birthDateDetailString = dateFormat.format(birthDate).trim();
|
||||
|
||||
Calendar c = Calendar.getInstance();
|
||||
int age = c.get(Calendar.YEAR) - calendarDetail.get(Calendar.YEAR);
|
||||
|
||||
if (c.get(Calendar.MONTH) < calendarDetail.get(Calendar.MONTH))
|
||||
age--;
|
||||
|
||||
ageDetail = new Integer(age).toString().trim();
|
||||
}
|
||||
|
||||
birthdayField.setText(birthDateDetailString);
|
||||
ageField.setText(ageDetail);
|
||||
|
||||
// Email details.
|
||||
contactDetails =
|
||||
accountInfoOpSet.getDetails(EmailAddressDetail.class);
|
||||
|
||||
String emailDetailString = "";
|
||||
while (contactDetails.hasNext())
|
||||
{
|
||||
emailDetail = (EmailAddressDetail) contactDetails.next();
|
||||
emailDetailString = emailDetailString + " "
|
||||
+ emailDetail.getDetailValue();
|
||||
}
|
||||
|
||||
emailField.setText(emailDetailString);
|
||||
|
||||
// Phone number details.
|
||||
contactDetails =
|
||||
accountInfoOpSet.getDetails(PhoneNumberDetail.class);
|
||||
|
||||
String phoneNumberDetailString = "";
|
||||
while (contactDetails.hasNext())
|
||||
{
|
||||
phoneDetail = (PhoneNumberDetail) contactDetails.next();
|
||||
phoneNumberDetailString =
|
||||
phoneNumberDetailString + " " + phoneDetail.getDetailValue();
|
||||
}
|
||||
|
||||
phoneField.setText(phoneNumberDetailString);
|
||||
}
|
||||
|
||||
/**
|
||||
* A panel that displays all of the details retrieved from the opSet.
|
||||
*/
|
||||
private void initExtendedPanel()
|
||||
{
|
||||
JPanel mainExtendedPanel = new JPanel(new BorderLayout());
|
||||
|
||||
JPanel extendedPanel = new JPanel();
|
||||
extendedPanel.setLayout(new BoxLayout(extendedPanel, BoxLayout.Y_AXIS));
|
||||
|
||||
JPanel imagePanel = new JPanel();
|
||||
|
||||
// The imagePanel will be used for any BinaryDetails and will be added at
|
||||
// the bottom so we don't disrupt the standard look of the other details
|
||||
imagePanel.setLayout(new BoxLayout(imagePanel, BoxLayout.LINE_AXIS));
|
||||
imagePanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
|
||||
.createTitledBorder(Resources.getString("userPictures")),
|
||||
BorderFactory.createEmptyBorder(0, 5, 5, 5)));
|
||||
|
||||
// Obtain all the details for a contact.
|
||||
Iterator iter = accountInfoOpSet.getAllAvailableDetails();
|
||||
|
||||
GenericDetail detail;
|
||||
JLabel detailLabel;
|
||||
JTextArea detailValueArea;
|
||||
JPanel detailPanel;
|
||||
|
||||
while (iter.hasNext())
|
||||
{
|
||||
detail = (GenericDetail) iter.next();
|
||||
|
||||
if (detail.getDetailValue().toString().equals(""))
|
||||
continue;
|
||||
|
||||
detailLabel = new JLabel();
|
||||
detailValueArea = new JTextArea();
|
||||
detailPanel = new JPanel(new BorderLayout(10, 10));
|
||||
|
||||
detailValueArea.setAlignmentX(JTextArea.CENTER_ALIGNMENT);
|
||||
detailValueArea.setLineWrap(true);
|
||||
detailValueArea.setEditable(true);
|
||||
|
||||
detailPanel.add(detailLabel, BorderLayout.WEST);
|
||||
detailPanel.add(detailValueArea, BorderLayout.CENTER);
|
||||
detailPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
|
||||
extendedPanel.add(detailPanel);
|
||||
|
||||
if (detail instanceof BinaryDetail)
|
||||
{
|
||||
JLabel imageLabel =
|
||||
new JLabel(new ImageIcon((byte[]) detail
|
||||
.getDetailValue()));
|
||||
|
||||
imagePanel.add(imageLabel);
|
||||
}
|
||||
else if (detail instanceof CalendarDetail)
|
||||
{
|
||||
detailLabel.setText(detail.getDetailDisplayName() + ": ");
|
||||
|
||||
Date detailDate =
|
||||
((Calendar) detail.getDetailValue()).getTime();
|
||||
DateFormat df = DateFormat.getDateInstance();
|
||||
|
||||
detailValueArea.setText(df.format(detailDate).trim());
|
||||
}
|
||||
else if (detail instanceof LocaleDetail)
|
||||
{
|
||||
detailLabel.setText(detail.getDetailDisplayName() + ": ");
|
||||
|
||||
detailValueArea.setText(((Locale) detail.getDetailValue())
|
||||
.getDisplayName().trim());
|
||||
}
|
||||
else if (detail instanceof TimeZoneDetail)
|
||||
{
|
||||
detailLabel.setText(detail.getDetailDisplayName() + ": ");
|
||||
|
||||
detailValueArea.setText(((TimeZone) detail.getDetailValue())
|
||||
.getDisplayName().trim());
|
||||
}
|
||||
else
|
||||
{
|
||||
detailLabel.setText(detail.getDetailDisplayName() + ": ");
|
||||
|
||||
detailValueArea.setText(
|
||||
detail.getDetailValue().toString().trim());
|
||||
}
|
||||
}
|
||||
|
||||
// If the contact's protocol supports web info, give them a button to
|
||||
// get it
|
||||
if (protocolProvider.getOperationSet(
|
||||
OperationSetWebContactInfo.class) != null)
|
||||
{
|
||||
final String urlString
|
||||
= ((OperationSetWebContactInfo) protocolProvider
|
||||
.getOperationSet(OperationSetWebContactInfo.class))
|
||||
.getWebContactInfo(
|
||||
protocolProvider.getAccountID().getAccountAddress())
|
||||
.toString();
|
||||
|
||||
JLabel webInfoLabel = new JLabel("Click to see web info: ");
|
||||
JEditorPane webInfoValue = new JEditorPane();
|
||||
JPanel webInfoPanel = new JPanel(new BorderLayout());
|
||||
|
||||
webInfoPanel.add(webInfoLabel, BorderLayout.WEST);
|
||||
webInfoPanel.add(webInfoValue, BorderLayout.CENTER);
|
||||
|
||||
extendedPanel.add(webInfoPanel);
|
||||
|
||||
webInfoValue.setOpaque(false);
|
||||
webInfoValue.setContentType("text/html");
|
||||
webInfoValue.setEditable(false);
|
||||
webInfoValue.setText( "<a href='"
|
||||
+ urlString + "'>"
|
||||
+ protocolProvider.getAccountID().getUserID()
|
||||
+ " web info</a>");
|
||||
|
||||
webInfoValue.addHyperlinkListener(new HyperlinkListener()
|
||||
{
|
||||
public void hyperlinkUpdate(HyperlinkEvent e)
|
||||
{
|
||||
if (e.getEventType()
|
||||
.equals(HyperlinkEvent.EventType.ACTIVATED))
|
||||
{
|
||||
AccountInfoActivator
|
||||
.getBrowserLauncher().openURL(urlString);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (imagePanel.getComponentCount() > 0)
|
||||
mainExtendedPanel.add(imagePanel, BorderLayout.CENTER);
|
||||
|
||||
mainExtendedPanel.add(extendedPanel, BorderLayout.NORTH);
|
||||
|
||||
this.mainPanel.add(mainExtendedPanel);
|
||||
|
||||
this.mainPanel.revalidate();
|
||||
this.mainPanel.repaint();
|
||||
}
|
||||
|
||||
private class SubmitActionListener implements ActionListener
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
String firstName = firstNameField.getText();
|
||||
String middleName = middleNameField.getText();
|
||||
String lastName = lastNameField.getText();
|
||||
String gender = genderField.getText();
|
||||
String email = emailField.getText();
|
||||
String phoneNumber = phoneField.getText();
|
||||
Icon avatar = avatarLabel.getIcon();
|
||||
|
||||
Calendar birthDateCalendar = Calendar.getInstance();
|
||||
|
||||
if(birthdayField.getText() != null
|
||||
&& birthdayField.getText().length() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
DateFormat dateFormat
|
||||
= DateFormat.getDateInstance(DateFormat.DEFAULT);
|
||||
|
||||
Date birthDate = dateFormat.parse(birthdayField.getText());
|
||||
|
||||
birthDateCalendar.setTime(birthDate);
|
||||
}
|
||||
catch (ParseException e2)
|
||||
{
|
||||
logger.error("Failed to parse birth date.", e2);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FirstNameDetail newFirstNameDetail
|
||||
= new ServerStoredDetails.FirstNameDetail(firstName);
|
||||
|
||||
if (firstNameDetail == null)
|
||||
accountInfoOpSet.addDetail(newFirstNameDetail);
|
||||
else
|
||||
accountInfoOpSet.replaceDetail( firstNameDetail,
|
||||
newFirstNameDetail);
|
||||
|
||||
// MiddleNameDetail newMiddleNameDetail
|
||||
// = new ServerStoredDetails.MiddleNameDetail(middleName);
|
||||
//
|
||||
// if (middleNameDetail == null)
|
||||
// accountInfoOpSet.addDetail(newMiddleNameDetail);
|
||||
// else
|
||||
// accountInfoOpSet.replaceDetail( middleNameDetail,
|
||||
// newMiddleNameDetail);
|
||||
|
||||
LastNameDetail newLastNameDetail
|
||||
= new ServerStoredDetails.LastNameDetail(lastName);
|
||||
|
||||
if (lastNameDetail == null)
|
||||
accountInfoOpSet.addDetail(newLastNameDetail);
|
||||
else
|
||||
accountInfoOpSet.replaceDetail( lastNameDetail,
|
||||
newLastNameDetail);
|
||||
|
||||
GenderDetail newGenderDetail
|
||||
= new ServerStoredDetails.GenderDetail(gender);
|
||||
|
||||
if (genderDetail == null)
|
||||
accountInfoOpSet.addDetail(newGenderDetail);
|
||||
else
|
||||
accountInfoOpSet.replaceDetail( genderDetail,
|
||||
newGenderDetail);
|
||||
|
||||
BirthDateDetail newBirthDateDetail
|
||||
= new ServerStoredDetails.BirthDateDetail(birthDateCalendar);
|
||||
|
||||
if (birthDateDetail == null)
|
||||
accountInfoOpSet.addDetail(newBirthDateDetail);
|
||||
else
|
||||
accountInfoOpSet.replaceDetail( birthDateDetail,
|
||||
newBirthDateDetail);
|
||||
|
||||
EmailAddressDetail newEmailDetail
|
||||
= new ServerStoredDetails.EmailAddressDetail(email);
|
||||
|
||||
if (emailDetail == null)
|
||||
accountInfoOpSet.addDetail(newEmailDetail);
|
||||
else
|
||||
accountInfoOpSet.replaceDetail( emailDetail,
|
||||
newEmailDetail);
|
||||
|
||||
PhoneNumberDetail newPhoneDetail
|
||||
= new ServerStoredDetails.PhoneNumberDetail(phoneNumber);
|
||||
|
||||
if (phoneDetail == null)
|
||||
accountInfoOpSet.addDetail(newPhoneDetail);
|
||||
else
|
||||
accountInfoOpSet.replaceDetail( phoneDetail,
|
||||
newPhoneDetail);
|
||||
|
||||
BinaryDetail newAvatarDetail
|
||||
= new ServerStoredDetails.BinaryDetail(
|
||||
"Avatar",
|
||||
newAvatarImage);
|
||||
|
||||
if (avatarDetail == null)
|
||||
accountInfoOpSet.addDetail(newAvatarDetail);
|
||||
else
|
||||
accountInfoOpSet.replaceDetail( avatarDetail,
|
||||
newAvatarDetail);
|
||||
}
|
||||
catch (ClassCastException e1)
|
||||
{
|
||||
logger.error("Failed to update account details.", e1);
|
||||
}
|
||||
catch (OperationFailedException e1)
|
||||
{
|
||||
logger.error("Failed to update account details.", e1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ChangeAvatarActionListener implements ActionListener
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
JFileChooser chooser = new JFileChooser(lastAvatarDir);
|
||||
|
||||
chooser.addChoosableFileFilter(new ImageFilter());
|
||||
|
||||
int returnVal = chooser.showOpenDialog(null);
|
||||
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION)
|
||||
{
|
||||
try
|
||||
{
|
||||
File file = chooser.getSelectedFile();
|
||||
lastAvatarDir = file.getParentFile();
|
||||
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
byte buffer[] = new byte[in.available()];
|
||||
in.read(buffer);
|
||||
|
||||
if (buffer == null || buffer.length <= 0)
|
||||
return;
|
||||
|
||||
newAvatarImage = buffer;
|
||||
|
||||
avatarLabel.setIcon(new ImageIcon(
|
||||
getScaledImageInstance(newAvatarImage)));
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.error("Failed to load image.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom filter that would accept only image files.
|
||||
*/
|
||||
private class ImageFilter extends FileFilter
|
||||
{
|
||||
/**
|
||||
* Accept all directories and all gif, jpg, tiff, or png files.
|
||||
*/
|
||||
public boolean accept(File f)
|
||||
{
|
||||
if (f.isDirectory())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
String extension = getExtension(f);
|
||||
if (extension != null)
|
||||
{
|
||||
if (extension.equals("tiff") ||
|
||||
extension.equals("tif") ||
|
||||
extension.equals("gif") ||
|
||||
extension.equals("jpeg") ||
|
||||
extension.equals("jpg") ||
|
||||
extension.equals("png"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extension of a file.
|
||||
*/
|
||||
public String getExtension(File f)
|
||||
{
|
||||
String ext = null;
|
||||
String s = f.getName();
|
||||
int i = s.lastIndexOf('.');
|
||||
|
||||
if (i > 0 && i < s.length() - 1) {
|
||||
ext = s.substring(i+1).toLowerCase();
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* The description of this filter.
|
||||
*/
|
||||
public String getDescription()
|
||||
{
|
||||
return Resources.getString("onlyMessages");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a scaled <tt>Image</tt> instance of the given byte image.
|
||||
*
|
||||
* @param image the image in bytes
|
||||
* @return a scaled <tt>Image</tt> instance of the given byte image.
|
||||
*/
|
||||
private Image getScaledImageInstance(byte[] image)
|
||||
{
|
||||
Image resultImage = null;
|
||||
|
||||
try
|
||||
{
|
||||
resultImage = ImageIO.read(
|
||||
new ByteArrayInputStream(image));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.error("Failed to convert bytes to image.", e);
|
||||
}
|
||||
|
||||
if(resultImage == null)
|
||||
return null;
|
||||
|
||||
return resultImage.getScaledInstance(
|
||||
avatarLabel.getWidth(),
|
||||
avatarLabel.getHeight(),
|
||||
Image.SCALE_SMOOTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the account details are loaded,
|
||||
* <code>false</code> - otherwise.
|
||||
*
|
||||
* @return <code>true</code> if the account details are loaded,
|
||||
* <code>false</code> - otherwise
|
||||
*/
|
||||
public boolean isDataLoaded()
|
||||
{
|
||||
return isDataLoaded;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.plugin.accountinfo;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
import net.java.sip.communicator.service.browserlauncher.*;
|
||||
import net.java.sip.communicator.service.gui.*;
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import net.java.sip.communicator.util.Logger;
|
||||
|
||||
import org.osgi.framework.*;
|
||||
|
||||
/**
|
||||
* Starts the account info bundle.
|
||||
*
|
||||
* @author Adam Glodstein
|
||||
*/
|
||||
public class AccountInfoActivator
|
||||
implements BundleActivator
|
||||
{
|
||||
private static Logger logger =
|
||||
Logger.getLogger(AccountInfoActivator.class.getName());
|
||||
|
||||
public static BundleContext bundleContext;
|
||||
|
||||
private static Map providerFactoriesMap = new Hashtable();
|
||||
|
||||
private static BrowserLauncherService browserLauncherService;
|
||||
|
||||
public void start(BundleContext bc) throws Exception
|
||||
{
|
||||
AccountInfoActivator.bundleContext = bc;
|
||||
|
||||
ServiceReference uiServiceRef =
|
||||
bc.getServiceReference(UIService.class.getName());
|
||||
|
||||
UIService uiService = (UIService) bc.getService(uiServiceRef);
|
||||
|
||||
ConfigurationWindow configWindow = uiService.getConfigurationWindow();
|
||||
configWindow.addConfigurationForm(new AccountInfoForm());
|
||||
}
|
||||
|
||||
public void stop(BundleContext bc) throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all <tt>ProtocolProviderFactory</tt>s obtained from the bundle
|
||||
* context.
|
||||
*
|
||||
* @return all <tt>ProtocolProviderFactory</tt>s obtained from the bundle
|
||||
* context
|
||||
*/
|
||||
public static Map getProtocolProviderFactories()
|
||||
{
|
||||
|
||||
ServiceReference[] serRefs = null;
|
||||
try
|
||||
{
|
||||
// get all registered provider factories
|
||||
serRefs =
|
||||
bundleContext.getServiceReferences(
|
||||
ProtocolProviderFactory.class.getName(), null);
|
||||
|
||||
}
|
||||
catch (InvalidSyntaxException e)
|
||||
{
|
||||
logger.error("LoginManager : " + e);
|
||||
}
|
||||
|
||||
for (int i = 0; i < serRefs.length; i++)
|
||||
{
|
||||
|
||||
ProtocolProviderFactory providerFactory =
|
||||
(ProtocolProviderFactory) bundleContext.getService(serRefs[i]);
|
||||
|
||||
providerFactoriesMap
|
||||
.put(serRefs[i].getProperty(ProtocolProviderFactory.PROTOCOL),
|
||||
providerFactory);
|
||||
}
|
||||
|
||||
return providerFactoriesMap;
|
||||
}
|
||||
|
||||
public static BrowserLauncherService getBrowserLauncher()
|
||||
{
|
||||
if (browserLauncherService == null)
|
||||
{
|
||||
ServiceReference serviceReference =
|
||||
bundleContext.getServiceReference(BrowserLauncherService.class
|
||||
.getName());
|
||||
|
||||
browserLauncherService =
|
||||
(BrowserLauncherService) bundleContext
|
||||
.getService(serviceReference);
|
||||
}
|
||||
|
||||
return browserLauncherService;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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.plugin.accountinfo;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import net.java.sip.communicator.service.gui.*;
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import net.java.sip.communicator.service.protocol.event.*;
|
||||
|
||||
import org.osgi.framework.*;
|
||||
|
||||
/**
|
||||
* A GUI plug-in for SIP Communicator that will allow users to set cross
|
||||
* protocol account information.
|
||||
*
|
||||
* @author Adam Goldstein
|
||||
*/
|
||||
public class AccountInfoForm
|
||||
extends JPanel
|
||||
implements ConfigurationForm
|
||||
{
|
||||
/**
|
||||
* The right side of the AccountInfo frame that contains protocol specific
|
||||
* account details.
|
||||
*/
|
||||
private AccountDetailsPanel detailsPanel;
|
||||
|
||||
private JTabbedPane accountsTabbedPane = new JTabbedPane();
|
||||
|
||||
private Hashtable<ProtocolProviderService, AccountDetailsPanel>
|
||||
accountsTable = new Hashtable();
|
||||
|
||||
/**
|
||||
* Constructs a frame with an AccuontInfoAccountPanel to display all
|
||||
* registered accounts on the left, and an information interface,
|
||||
* AccountDetailsPanel, on the right.
|
||||
*
|
||||
* @param metaContact
|
||||
*/
|
||||
public AccountInfoForm()
|
||||
{
|
||||
super(new BorderLayout());
|
||||
|
||||
Set set = AccountInfoActivator.getProtocolProviderFactories().entrySet();
|
||||
Iterator iter = set.iterator();
|
||||
|
||||
boolean hasRegisteredAccounts = false;
|
||||
|
||||
while (iter.hasNext())
|
||||
{
|
||||
Map.Entry entry = (Map.Entry) iter.next();
|
||||
|
||||
ProtocolProviderFactory providerFactory
|
||||
= (ProtocolProviderFactory) entry.getValue();
|
||||
|
||||
ArrayList accountsList = providerFactory.getRegisteredAccounts();
|
||||
|
||||
AccountID accountID;
|
||||
ServiceReference serRef;
|
||||
ProtocolProviderService protocolProvider;
|
||||
|
||||
for (int i = 0; i < accountsList.size(); i++)
|
||||
{
|
||||
accountID = (AccountID) accountsList.get(i);
|
||||
|
||||
boolean isHidden =
|
||||
accountID.getAccountProperties().get("HIDDEN_PROTOCOL") != null;
|
||||
|
||||
if(!isHidden)
|
||||
hasRegisteredAccounts = true;
|
||||
|
||||
serRef = providerFactory.getProviderForAccount(accountID);
|
||||
|
||||
protocolProvider = (ProtocolProviderService) AccountInfoActivator
|
||||
.bundleContext.getService(serRef);
|
||||
|
||||
detailsPanel = new AccountDetailsPanel(protocolProvider);
|
||||
|
||||
accountsTable.put(protocolProvider, detailsPanel);
|
||||
|
||||
protocolProvider.addRegistrationStateChangeListener(
|
||||
new RegistrationStateChangeListenerImpl());
|
||||
|
||||
this.accountsTabbedPane.addTab(
|
||||
accountID.getUserID(), detailsPanel);
|
||||
}
|
||||
}
|
||||
|
||||
this.add(accountsTabbedPane, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title of this configuration form.
|
||||
*
|
||||
* @return the icon of this configuration form.
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return Resources.getString("title");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the icon of this configuration form.
|
||||
*
|
||||
* @return the icon of this configuration form.
|
||||
*/
|
||||
public byte[] getIcon()
|
||||
{
|
||||
return Resources.getImageInBytes("infoIcon");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the form of this configuration form.
|
||||
*
|
||||
* @return the form of this configuration form.
|
||||
*/
|
||||
public Object getForm()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
private class RegistrationStateChangeListenerImpl
|
||||
implements RegistrationStateChangeListener
|
||||
{
|
||||
public void registrationStateChanged(RegistrationStateChangeEvent evt)
|
||||
{
|
||||
ProtocolProviderService protocolProvider = evt.getProvider();
|
||||
|
||||
if (protocolProvider.getOperationSet(
|
||||
OperationSetServerStoredAccountInfo.class) != null
|
||||
&& evt.getNewState() == RegistrationState.REGISTERED)
|
||||
{
|
||||
if (accountsTable.containsKey(protocolProvider))
|
||||
{
|
||||
AccountDetailsPanel detailsPanel
|
||||
= accountsTable.get(protocolProvider);
|
||||
|
||||
if(!detailsPanel.isDataLoaded())
|
||||
detailsPanel.loadDetails();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.plugin.accountinfo;
|
||||
|
||||
import java.awt.image.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.swing.*;
|
||||
|
||||
import net.java.sip.communicator.util.*;
|
||||
/**
|
||||
* The Messages class manages the access to the internationalization
|
||||
* properties files.
|
||||
* @author Yana Stamcheva
|
||||
*/
|
||||
public class Resources {
|
||||
|
||||
private static Logger log = Logger.getLogger(Resources.class);
|
||||
|
||||
private static final String BUNDLE_NAME
|
||||
= "net.java.sip.communicator.plugin.accountinfo.resources";
|
||||
|
||||
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
|
||||
.getBundle(BUNDLE_NAME);
|
||||
|
||||
/**
|
||||
* Returns an internationalized string corresponding to the given key.
|
||||
* @param key The key of the string.
|
||||
* @return An internationalized string corresponding to the given key.
|
||||
*/
|
||||
public static String getString(String key) {
|
||||
try {
|
||||
return RESOURCE_BUNDLE.getString(key);
|
||||
|
||||
} catch (MissingResourceException e) {
|
||||
|
||||
return '!' + key + '!';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an image from a given image identifier.
|
||||
* @param imageID The identifier of the image.
|
||||
* @return The image for the given identifier.
|
||||
*/
|
||||
public static ImageIcon getImage(String imageID) {
|
||||
BufferedImage image = null;
|
||||
|
||||
String path = Resources.getString(imageID);
|
||||
try {
|
||||
image = ImageIO.read(Resources.class.getClassLoader()
|
||||
.getResourceAsStream(path));
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to load image:" + path, e);
|
||||
}
|
||||
|
||||
return new ImageIcon(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an image from a given image identifier.
|
||||
* @param imageID The identifier of the image.
|
||||
* @return The image for the given identifier.
|
||||
*/
|
||||
public static byte[] getImageInBytes(String imageID) {
|
||||
byte[] image = new byte[100000];
|
||||
|
||||
String path = Resources.getString(imageID);
|
||||
try {
|
||||
Resources.class.getClassLoader()
|
||||
.getResourceAsStream(path).read(image);
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to load image:" + path, e);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
Bundle-Activator: net.java.sip.communicator.plugin.accountinfo.AccountInfoActivator
|
||||
Bundle-Name: Contact Info
|
||||
Bundle-Description: A plug-in that can set cross protocol account info.
|
||||
Bundle-Vendor: sip-communicator.org
|
||||
Bundle-Version: 0.0.1
|
||||
Import-Package: org.osgi.framework,
|
||||
net.java.sip.communicator.util,
|
||||
net.java.sip.communicator.service.contactlist,
|
||||
net.java.sip.communicator.service.contactlist.event,
|
||||
net.java.sip.communicator.service.gui,
|
||||
net.java.sip.communicator.service.gui.event,
|
||||
net.java.sip.communicator.service.protocol,
|
||||
net.java.sip.communicator.service.protocol.event,
|
||||
net.java.sip.communicator.service.browserlauncher,
|
||||
javax.swing,
|
||||
javax.swing.event,
|
||||
javax.swing.table,
|
||||
javax.swing.text,
|
||||
javax.swing.text.html,
|
||||
javax.accessibility,
|
||||
javax.swing.plaf,
|
||||
javax.swing.plaf.metal,
|
||||
javax.swing.plaf.basic,
|
||||
javax.imageio,
|
||||
javax.swing.filechooser,
|
||||
javax.swing.tree,
|
||||
javax.swing.undo,
|
||||
javax.swing.border
|
||||
@ -0,0 +1,25 @@
|
||||
accountInfo=Account info for
|
||||
title=Account Info
|
||||
apply=Apply
|
||||
browse=Browse
|
||||
selectAccount=Select account
|
||||
summary=Summary
|
||||
summaryDesc=Summary of account info for
|
||||
extended=Extended
|
||||
extendedDesc=Extended account info for
|
||||
notSupported=Account info not available.
|
||||
clickWeb=Click for Web Info
|
||||
webInfo=Web Info
|
||||
firstNameNS=First Name:
|
||||
middleNameNS=Middle Name:
|
||||
lastNameNS=Last Name:
|
||||
ageNS=Age:
|
||||
bdayNS=Birth Date:
|
||||
genderNS=Gender:
|
||||
emailNS=E-mail:
|
||||
phoneNS=Phone:
|
||||
userPictures=User Pictures
|
||||
change=Change
|
||||
onlyMessages=Only messages
|
||||
infoIcon=resources/images/plugin/accountinfo/userInfo16x16.png
|
||||
defaultPersonIcon=resources/images/plugin/accountinfo/personPhoto.png
|
||||
Loading…
Reference in new issue