package org.limewire.ui.swing.library.sharing; import java.awt.CardLayout; import java.awt.Color; import java.awt.Dimension; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.SwingUtilities; import org.jdesktop.application.Resource; import org.limewire.core.api.library.SharedFileList; import org.limewire.friend.api.FriendConnectionEvent; import org.limewire.friend.api.FriendEvent; import org.limewire.friend.api.FriendConnectionEvent.Type; import org.limewire.inject.LazySingleton; import org.limewire.listener.EventBean; import org.limewire.listener.EventListener; import org.limewire.listener.ListenerSupport; import org.limewire.listener.SwingEDTEvent; import org.limewire.ui.swing.friends.login.AutoLoginService; import org.limewire.ui.swing.settings.SwingUiSettings; import org.limewire.ui.swing.util.GuiUtils; import ca.odell.glazedlists.event.ListEvent; import ca.odell.glazedlists.event.ListEventListener; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.name.Named; /** * The panel in all shared lists that contains either the login view, the list * of friends the list is shared with, or a way of editing the list of friends. */ @LazySingleton public class LibrarySharingPanel { /** * Property string for whether the sharing panel is in edit * mode or not. */ public static final String EDIT_MODE = "EDIT_MODE"; @Resource private Color backgroundColor; @Resource private Color borderColor; private static final String LOGIN_VIEW = "LOGIN_VIEW"; private static final String EDITABLE_VIEW = "EDITABLE_VIEW"; private static final String FRIEND_LIST_VIEW = "FRIEND_LIST_VIEW"; private final Provider<LibrarySharingLoginPanel> loginPanelProvider; private final Provider<LibrarySharingFriendListPanel> friendListPanelProvider; private final Provider<LibrarySharingEditablePanel> editablePanelProvider; private final Provider<AutoLoginService> autoLoginServiceProvider; // these are all lazily created. private LibrarySharingLoginPanel loginPanel; private LibrarySharingFriendListPanel friendListPanel; private LibrarySharingEditablePanel editablePanel; private final JPanel component; private final CardLayout layout = new CardLayout(); private final Map<String, JComponent> layoutMap = new HashMap<String, JComponent>(); private final EventBean<FriendConnectionEvent> connectionEvent; private final ListEventListener<String> friendsListener; private enum View { NONE, LOGIN, FRIEND_LIST, EDIT_LIST } private View currentView = View.NONE; private SharedFileList currentList; @Inject public LibrarySharingPanel(Provider<LibrarySharingLoginPanel> loginPanel, Provider<LibrarySharingFriendListPanel> nonEditablePanel, Provider<LibrarySharingEditablePanel> editablePanel, EventBean<FriendConnectionEvent> connectionEvent, Provider<AutoLoginService> autoLoginServiceProvider) { this.loginPanelProvider = loginPanel; this.friendListPanelProvider = nonEditablePanel; this.editablePanelProvider = editablePanel; this.connectionEvent = connectionEvent; this.friendsListener = new FriendsListener(); this.autoLoginServiceProvider = autoLoginServiceProvider; GuiUtils.assignResources(this); component = new JPanel(); component.setMaximumSize(new Dimension(134, Integer.MAX_VALUE)); component.setBackground(backgroundColor); component.setVisible(false); component.setBorder(BorderFactory.createMatteBorder(0,0,0,1, borderColor)); component.setLayout(layout); } @Inject void register(ListenerSupport<FriendConnectionEvent> connectionEvent, @Named("known") ListenerSupport<FriendEvent> friendSupport) { connectionEvent.addListener(new EventListener<FriendConnectionEvent>() { @Override @SwingEDTEvent public void handleEvent(FriendConnectionEvent event) { if(component.isVisible()) { if(!isLoggedIn()) { showLoginView(); } else if(currentView == View.LOGIN) { if(SwingUiSettings.SHOW_SHARING_OVERLAY_MESSAGE.getValue()) { showEditableView(); } else { showFriendListView(); } } } } }); friendSupport.addListener(new EventListener<FriendEvent>() { @Override @SwingEDTEvent public void handleEvent(FriendEvent event) { if(currentView == View.EDIT_LIST) { editablePanel.refreshSelectedList(); } } }); } void showLoginView() { if(!layoutMap.containsKey(LOGIN_VIEW)) { loginPanel = loginPanelProvider.get(); JComponent newComponent = loginPanel.getComponent(); component.add(newComponent, LOGIN_VIEW); layoutMap.put(LOGIN_VIEW, newComponent); } currentView = View.LOGIN; loginPanel.setLoggingIn(isLoggingIn()); sharesChanged(); getComponent().firePropertyChange(EDIT_MODE, true, false); layout.show(component, LOGIN_VIEW); } void showEditableView() { if(!layoutMap.containsKey(EDITABLE_VIEW)) { editablePanel = editablePanelProvider.get(); JComponent newComponent = editablePanel.getComponent(); component.add(newComponent, EDITABLE_VIEW); layoutMap.put(EDITABLE_VIEW, newComponent); } currentView = View.EDIT_LIST; editablePanel.editWithSelectedIds(currentList.getFriendIds()); getComponent().firePropertyChange(EDIT_MODE, false, true); layout.show(component, EDITABLE_VIEW); } void showFriendListView() { if(!layoutMap.containsKey(FRIEND_LIST_VIEW)) { friendListPanel = friendListPanelProvider.get(); JComponent newComponent = friendListPanel.getComponent(); component.add(newComponent, FRIEND_LIST_VIEW); layoutMap.put(FRIEND_LIST_VIEW, newComponent); } currentView = View.FRIEND_LIST; sharesChanged(); getComponent().firePropertyChange(EDIT_MODE, true, false); layout.show(component, FRIEND_LIST_VIEW); } /** Stops sharing the current list with any friends. */ void stopSharing() { currentList.setFriendList(Collections.<String>emptyList()); } /** Sets the new list of IDs that should be shared. */ void setFriendIdsForSharing(List<String> friendIds) { currentList.setFriendList(friendIds); } private void sharesChanged() { if(currentList != null) { switch(currentView) { case FRIEND_LIST: friendListPanel.setSharedFriendIds(currentList.getFriendIds()); break; case LOGIN: loginPanel.setSharedFriendIds(currentList.getFriendIds()); break; } } } /** Sets a new backing SharedFileList that this sharing panel will use. */ public void setSharedFileList(SharedFileList newList) { if(currentList != newList) { if(currentList != null) { currentList.getFriendIds().removeListEventListener(friendsListener); } currentList = newList; currentList.getFriendIds().addListEventListener(friendsListener); } // view may have changed based on sign out/sign in event if(isLoggedIn()) { if(SwingUiSettings.SHOW_SHARING_OVERLAY_MESSAGE.getValue()) { showEditableView(); } else { showFriendListView(); } } else { showLoginView(); } } /** * Enable the edit view if possible. */ public void showEditMode() { if(isLoggedIn()) { showEditableView(); } } public JComponent getComponent() { return component; } private boolean isLoggedIn() { if(connectionEvent.getLastEvent() == null) { return false; } else { return connectionEvent.getLastEvent().getType() == Type.CONNECTED; } } private boolean isLoggingIn() { if (autoLoginServiceProvider.get().isAttemptingLogin()) { return true; } if(connectionEvent.getLastEvent() == null) { return false; } else { return connectionEvent.getLastEvent().getType() == Type.CONNECTING; } } private class FriendsListener implements ListEventListener<String> { @Override public void listChanged(final ListEvent<String> listChanges) { SwingUtilities.invokeLater(new Runnable() { public void run() { sharesChanged(); } }); } } }