/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.java.sip.communicator.impl.gui.main.chatroomslist;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.*;
import net.java.sip.communicator.impl.gui.main.chat.*;
import net.java.sip.communicator.plugin.desktoputil.*;
import net.java.sip.communicator.service.muc.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
/**
* The dialog containing a list of all chat rooms of the user and
* also interface for create a new chat room, join a chat room, search all
* chat rooms, etc.
*
* @author Yana Stamcheva
* @author Lyubomir Marinov
* @author Damian Minkov
*/
public class ChatRoomTableDialog
extends SIPCommDialog
implements ActionListener
{
/**
* Whether we should remove the room if it fails to join when adding it.
*/
private static final String REMOVE_ROOM_ON_FIRST_JOIN_FAILED
= "net.java.sip.communicator.impl.gui.main.chatroomslist." +
"REMOVE_ROOM_ON_FIRST_JOIN_FAILED";
/**
* Whether we should make rooms autojoin by default.
*/
private static final String ENABLE_ROOM_AUTO_JOIN_ON_CREATION
= "net.java.sip.communicator.impl.gui.main.chatroomslist." +
"ENABLE_ROOM_AUTO_JOIN_ON_CREATION";
/**
* The global/shared ChatRoomTableDialog
currently showing.
*/
private static ChatRoomTableDialog chatRoomTableDialog;
/**
* A JComboBox which will allow to select an account for joining a room.
*/
private JComboBox providersCombo;
/**
* The ok button.
*/
private final JButton okButton
= new JButton(
GuiActivator.getResources().getI18NString("service.gui.JOIN"));
/**
* The cancel button.
*/
private final JButton cancelButton
= new JButton(
GuiActivator.getResources().getI18NString(
"service.gui.CANCEL"));
/**
* The list button. This button lists the existing chat rooms on the server.
*/
private final JButton listButton
= new JButton(GuiActivator.getResources().getI18NString(
"service.gui.LIST"));
/**
* The editor for the chat room name.
*/
private JTextField chatRoomNameField = null;
/**
* Label that hides and shows the more fields panel on click.
*/
private JLabel cmdExpandMoreFields;
/**
* Panel that holds the subject field and the nickname field.
*/
private JPanel moreFieldsPannel = new JPanel(new BorderLayout(5, 5));
/**
* The field for the nickname.
*/
private JTextField nicknameField = new JTextField();
/**
* Text field for the subject.
*/
private SIPCommTextField subject = new SIPCommTextField(DesktopUtilActivator
.getResources().getI18NString("service.gui.SUBJECT"));
/**
* The dialog for the existing chat rooms on the server.
*/
private ServerChatRoomsChoiceDialog serverChatRoomsChoiceDialog = null;
/**
* The ChatRoomList.ChatRoomProviderWrapperListener instance which
* has been registered with {@link #chatRoomList} and which is to be
* unregistered when this instance is disposed in order to prevent this
* instance from leaking.
*/
private final ChatRoomProviderWrapperListener
chatRoomProviderWrapperListener
= new ChatRoomProviderWrapperListener()
{
public void chatRoomProviderWrapperAdded(
ChatRoomProviderWrapper provider)
{
providersCombo.addItem(provider);
}
public void chatRoomProviderWrapperRemoved(
ChatRoomProviderWrapper provider)
{
providersCombo.removeItem(provider);
}
};
/**
* Shows a ChatRoomTableDialog
creating it first if necessary.
* The shown instance is shared in order to prevent displaying multiple
* instances of one and the same ChatRoomTableDialog
.
*/
public static void showChatRoomTableDialog()
{
if (chatRoomTableDialog == null)
{
chatRoomTableDialog
= new ChatRoomTableDialog(
GuiActivator.getUIService().getMainFrame());
/*
* When the global/shared ChatRoomTableDialog closes, don't keep a
* reference to it and let it be garbage-collected.
*/
chatRoomTableDialog.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosed(WindowEvent e)
{
if (chatRoomTableDialog == e.getWindow())
chatRoomTableDialog = null;
}
});
}
chatRoomTableDialog.setVisible(true);
chatRoomTableDialog.pack();
}
/**
* Creates an instance of MyChatRoomsDialog by specifying the
* parent window.
*
* @param parentWindow the parent window of this dialog
*/
public ChatRoomTableDialog(MainFrame parentWindow)
{
super(parentWindow);
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
this.setTitle(GuiActivator.getResources()
.getI18NString("service.gui.MY_CHAT_ROOMS_TITLE"));
this.init();
}
/**
* Initializes this chat room dialog.
*/
private void init()
{
this.getContentPane().setLayout(new BorderLayout(5,5));
JPanel northPanel = new TransparentPanel(new BorderLayout(5, 5));
northPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 5, 15));
JPanel labels = new TransparentPanel(new GridLayout(2, 2, 5, 5));
labels.add(new JLabel(GuiActivator.getResources()
.getI18NString("service.gui.ACCOUNT")));
labels.add(new JLabel(GuiActivator.getResources()
.getI18NString("service.gui.ROOM_NAME")));
JPanel valuesPanel = new TransparentPanel(new GridLayout(2, 2, 5, 5));
providersCombo = createProvidersCombobox();
chatRoomNameField = new JTextField();
valuesPanel.add(providersCombo);
valuesPanel.add(chatRoomNameField);
northPanel.add(labels, BorderLayout.WEST);
northPanel.add(valuesPanel, BorderLayout.CENTER);
northPanel.setPreferredSize(new Dimension(600, 80));
JPanel buttonPanel = new TransparentPanel(new BorderLayout(5, 5));
buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15));
JPanel eastButtonPanel = new TransparentPanel();
JPanel westButtonPanel = new TransparentPanel();
okButton.addActionListener(this);
cancelButton.addActionListener(this);
listButton.addActionListener(this);
okButton.setToolTipText(GuiActivator.getResources()
.getI18NString("service.gui.JOIN_CHAT_ROOM"));
updateOKButtonEnableState();
eastButtonPanel.add(cancelButton);
eastButtonPanel.add(okButton);
westButtonPanel.add(listButton);
buttonPanel.add(eastButtonPanel, BorderLayout.EAST);
buttonPanel.add(westButtonPanel, BorderLayout.WEST);
this.getContentPane().add(northPanel, BorderLayout.NORTH);
this.getContentPane().add(initMoreFields(), BorderLayout.CENTER);
this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
KeyListener keyListener = new KeyListener() {
public void keyTyped(KeyEvent e)
{}
public void keyPressed(KeyEvent e)
{}
public void keyReleased(KeyEvent e)
{
updateOKButtonEnableState();
if (e.getKeyCode() == KeyEvent.VK_ENTER && okButton.isEnabled())
{
okButton.doClick();
}
}
};
// when we are typing we clear any selection in the available and saved
// rooms
chatRoomNameField.addKeyListener(keyListener);
nicknameField.addKeyListener(keyListener);
providersCombo.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent event)
{
setNickname(
(ChatRoomProviderWrapper)providersCombo.getSelectedItem());
if(serverChatRoomsChoiceDialog != null)
serverChatRoomsChoiceDialog.changeProtocolProvider(
getSelectedProvider());
}
});
//register listener to listen for newly added chat room providers
// and for removed ones
GuiActivator.getMUCService().addChatRoomProviderWrapperListener(
chatRoomProviderWrapperListener);
}
/**
* Updates the enable/disable state of the OK button.
*/
private void updateOKButtonEnableState()
{
okButton.setEnabled(
(chatRoomNameField.getText() != null
&& chatRoomNameField.getText().trim().length() > 0)
&& (nicknameField.getText() != null
&& nicknameField.getText().trim().length() > 0));
}
/**
* Sets the default value in the nickname field based on chat room provider.
* @param provider the provider
*/
private void setNickname(ChatRoomProviderWrapper provider)
{
if (provider == null)
{
return;
}
nicknameField.setText(
GuiActivator.getGlobalDisplayDetailsService().getDisplayName(
provider.getProtocolProvider()));
updateOKButtonEnableState();
}
/**
* Constructs the more label and the fields related to the label and returns
* them.
* @return the more label and the fields related to the label
*/
private Component initMoreFields()
{
JPanel morePanel = new TransparentPanel(new BorderLayout());
morePanel.setOpaque(false);
morePanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 5, 15));
moreFieldsPannel.setBorder(
BorderFactory.createEmptyBorder(10, 30, 0, 0));
moreFieldsPannel.setOpaque(false);
moreFieldsPannel.setVisible(false);
JPanel subjectPanel = new TransparentPanel(new BorderLayout());
subject.setFont(getFont().deriveFont(12f));
subjectPanel.add(subject,BorderLayout.NORTH);
moreFieldsPannel.add(subjectPanel, BorderLayout.CENTER);
JPanel nicknamePanel = new TransparentPanel(new BorderLayout(5, 5));
setNickname((ChatRoomProviderWrapper)providersCombo.getSelectedItem());
nicknamePanel.add(nicknameField, BorderLayout.CENTER);
nicknamePanel.add(new JLabel(
GuiActivator.getResources().getI18NString("service.gui.NICKNAME")),
BorderLayout.WEST);
moreFieldsPannel.add(nicknamePanel,BorderLayout.NORTH);
cmdExpandMoreFields = new JLabel();
cmdExpandMoreFields.setBorder(new EmptyBorder(0, 5, 0, 0));
cmdExpandMoreFields.setIcon(DesktopUtilActivator.getResources()
.getImage("service.gui.icons.RIGHT_ARROW_ICON"));
cmdExpandMoreFields.setText(DesktopUtilActivator
.getResources().getI18NString("service.gui.MORE_LABEL"));
cmdExpandMoreFields.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
cmdExpandMoreFields.setIcon(
GuiActivator.getResources().getImage(
moreFieldsPannel.isVisible()
? "service.gui.icons.RIGHT_ARROW_ICON"
: "service.gui.icons.DOWN_ARROW_ICON"));
moreFieldsPannel.setVisible(
!moreFieldsPannel.isVisible());
pack();
}
});
morePanel.add(cmdExpandMoreFields,BorderLayout.NORTH);
morePanel.add(moreFieldsPannel,BorderLayout.CENTER);
return morePanel;
}
/**
* Creates the providers combobox and filling its content.
* @return
*/
private JComboBox createProvidersCombobox()
{
Iterator providers
= GuiActivator.getMUCService().getChatRoomProviders();
JComboBox chatRoomProvidersCombobox = new JComboBox();
while (providers.hasNext())
chatRoomProvidersCombobox.addItem(providers.next());
chatRoomProvidersCombobox.setRenderer(new ChatRoomProviderRenderer());
return chatRoomProvidersCombobox;
}
/**
* Handles ActionEvents triggered by a button click.
* @param e the action event.
*/
public void actionPerformed(ActionEvent e)
{
String subject = null;
JButton sourceButton = (JButton) e.getSource();
if(sourceButton.equals(okButton))
{
if((chatRoomNameField.getText() != null
&& chatRoomNameField.getText().trim().length() > 0)
&& (nicknameField.getText() != null
&& nicknameField.getText().trim().length() > 0))
{
final ChatRoomWrapper chatRoomWrapper =
GuiActivator.getMUCService().createChatRoom(
chatRoomNameField.getText().trim(),
getSelectedProvider().getProtocolProvider(),
new ArrayList(),
"",
false,
false,
false);
if (chatRoomWrapper == null)
{
// In case the protocol failed to create a chat room, null
// is returned, so we can stop preparing the UI to open the
// (null) chat room.
return;
}
if(!chatRoomWrapper.isPersistent())
{
chatRoomWrapper.setPersistent(true);
ConfigurationUtils.saveChatRoom(
chatRoomWrapper.getParentProvider()
.getProtocolProvider(),
chatRoomWrapper.getChatRoomID(),
chatRoomWrapper.getChatRoomID(),
chatRoomWrapper.getChatRoomName());
if(GuiActivator.getConfigurationService()
.getBoolean(ENABLE_ROOM_AUTO_JOIN_ON_CREATION, false))
{
chatRoomWrapper.setAutoJoin(true);
}
}
String nickName = nicknameField.getText().trim();
ConfigurationUtils.updateChatRoomProperty(
chatRoomWrapper.getParentProvider().getProtocolProvider(),
chatRoomWrapper.getChatRoomID(), "userNickName", nickName);
subject = this.subject.getText();
if(nickName == null)
return;
if(GuiActivator.getConfigurationService()
.getBoolean(REMOVE_ROOM_ON_FIRST_JOIN_FAILED, false))
{
chatRoomWrapper.addPropertyChangeListener(
new PropertyChangeListener()
{
@Override
public void propertyChange(PropertyChangeEvent evt)
{
if(evt.getPropertyName()
.equals(ChatRoomWrapper.JOIN_SUCCESS_PROP))
return;
// if we failed for some reason we want to
// remove the room
// close the room
GuiActivator.getUIService()
.closeChatRoomWindow(chatRoomWrapper);
// remove it
GuiActivator.getMUCService()
.removeChatRoom(chatRoomWrapper);
}
}
);
}
GuiActivator.getMUCService()
.joinChatRoom(chatRoomWrapper, nickName, null, subject);
ChatWindowManager chatWindowManager =
GuiActivator.getUIService().getChatWindowManager();
ChatPanel chatPanel =
chatWindowManager.getMultiChat(chatRoomWrapper, true);
chatWindowManager.openChat(chatPanel, true);
}
// in all cases we dispose this dialog
dispose();
}
else if(sourceButton.equals(cancelButton))
{
dispose();
}
else if(sourceButton.equals(listButton))
{
if(serverChatRoomsChoiceDialog == null)
{
serverChatRoomsChoiceDialog = new ServerChatRoomsChoiceDialog(
getTitle(), getSelectedProvider());
}
serverChatRoomsChoiceDialog.setVisible(true);
}
}
@Override
protected void close(boolean isEscaped)
{
dispose();
}
/**
* Releases the resources allocated by this instance throughout its
* lifetime.
*/
@Override
public void dispose()
{
if (chatRoomTableDialog == this)
chatRoomTableDialog = null;
GuiActivator.getMUCService().removeChatRoomProviderWrapperListener(
chatRoomProviderWrapperListener);
if(serverChatRoomsChoiceDialog != null)
{
serverChatRoomsChoiceDialog.dispose();
serverChatRoomsChoiceDialog = null;
}
super.dispose();
}
/**
* Returns the selected provider in the providers combo box.
*
* @return the selected provider
*/
public ChatRoomProviderWrapper getSelectedProvider()
{
return (ChatRoomProviderWrapper)providersCombo.getSelectedItem();
}
/**
* Sets the value of chat room name field.
* @param chatRoom the chat room name.
*/
public void setChatRoomNameField(String chatRoom)
{
this.chatRoomNameField.setText(chatRoom);
updateOKButtonEnableState();
}
/**
* Sets the value of chat room name field in the current
* ChatRoomTableDialog instance.
* @param chatRoom the chat room name.
*/
public static void setChatRoomField(String chatRoom)
{
if(chatRoomTableDialog != null)
{
chatRoomTableDialog.setChatRoomNameField(chatRoom);
}
}
/**
* Cell renderer for the providers combo box: displays the protocol name
* with its associated icon.
*/
class ChatRoomProviderRenderer
extends JLabel
implements ListCellRenderer
{
/**
* The renderer.
*/
public ChatRoomProviderRenderer()
{
setOpaque(true);
setHorizontalAlignment(LEFT);
setVerticalAlignment(CENTER);
this.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 5));
}
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus)
{
ChatRoomProviderWrapper provider = (ChatRoomProviderWrapper)value;
if(provider == null)
return this;
if (isSelected)
{
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
}
else
{
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setText(provider.getProtocolProvider()
.getAccountID().getDisplayName());
setIcon(new ImageIcon(provider.getProtocolProvider()
.getProtocolIcon().getIcon(ProtocolIcon.ICON_SIZE_16x16)));
return this;
}
}
}