/* * 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.utils; import java.awt.datatransfer.*; import java.io.*; import java.util.*; import javax.swing.*; import net.java.sip.communicator.impl.gui.main.contactlist.*; import net.java.sip.communicator.plugin.desktoputil.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; /** * A TransferHandler that we use to handle dropping of <tt>UIContact</tt>s or * simple string addresses to the conference invite dialog. * * @author Sebastien Vincent * @author Yana Stamcheva */ public class InviteContactTransferHandler extends ExtendedTransferHandler { /** * Serial version UID. */ private static final long serialVersionUID = 0L; /** * The logger. */ private static final Logger logger = Logger.getLogger(InviteContactTransferHandler.class); /** * The data flavor used when transferring <tt>UIContact</tt>s. */ protected static final DataFlavor uiContactDataFlavor = new DataFlavor(UIContact.class, "UIContact"); /** * The destination contact list. */ private final ContactList contactList; /** * The backup provider to use if no provider is specified. */ private ProtocolProviderService backupProvider; /** * If the component is the selected contact list or not */ private final boolean selected; /** * Indicates that this handler is of type source transfer handler. */ public static final int SOURCE_TRANSFER_HANDLER = 0; /** * Indicates that this handler is of type destination transfer handler. */ public static final int DEST_TRANSFER_HANDLER = 1; /** * The type of this transfer handler. Indicates if it's used for dragging * from the source contact list, or dropping in the destination contact * list. */ private final int type; /** * Constructor. * * @param contactList the contact list, this transfer handler is about * @param type the type of this transfer handler. Indicates if it's used for * dragging from the source contact list, or dropping in the destination * contact list. One of SOURCE_TRANSFER_HANDLER or DEST_TRANSFER_HANDLER * @param selected if the column is the selected ones */ public InviteContactTransferHandler(ContactList contactList, int type, boolean selected) { this.contactList = contactList; this.type = type; this.selected = selected; } /** * Creates a transferable for text pane components in order to enable drag * and drop of text. * * @param component the component for which to create a * <tt>Transferable</tt> * @return the created <tt>Transferable</tt> */ @Override protected Transferable createTransferable(JComponent component) { // Dragging is only enabled in the source contact list. if (type != SOURCE_TRANSFER_HANDLER) return null; if (component instanceof ContactList) { List<UIContact> c = ((ContactList) component).getSelectedContacts(); if (c != null) return new UIContactTransferable(c); } return super.createTransferable(component); } /** * Indicates whether a component will accept an import of the given * set of data flavors prior to actually attempting to import it. We return * <tt>true</tt> to indicate that the transfer with at least one of the * given flavors would work and <tt>false</tt> to reject the transfer. * <p> * @param comp component * @param flavor the data formats available * @return true if the data can be inserted into the component, false * otherwise * @throws NullPointerException if <code>support</code> is {@code null} */ @Override public boolean canImport(JComponent comp, DataFlavor flavor[]) { // Dropping is only enabled in the destination contact list. if (type != DEST_TRANSFER_HANDLER) return false; for (int i = 0, n = flavor.length; i < n; i++) { if (flavor[i].equals(uiContactDataFlavor)) { if (comp instanceof ContactList) { return true; } return false; } } return false; } /** * Handles transfers to the invite dialog. * * @param comp the component to receive the transfer; * @param t the data to import * @return true if the data was inserted into the component and false * otherwise */ @Override public boolean importData(JComponent comp, Transferable t) { if (t.isDataFlavorSupported(uiContactDataFlavor)) { if(!selected) return false; Object o = null; try { o = t.getTransferData(uiContactDataFlavor); } catch (UnsupportedFlavorException e) { if (logger.isDebugEnabled()) logger.debug("Failed to drop meta contact.", e); } catch (IOException e) { if (logger.isDebugEnabled()) logger.debug("Failed to drop meta contact.", e); } if (o instanceof Collection) { Iterator<?> c = ((Collection<?>) o).iterator(); while (c.hasNext()) { Object nextO = c.next(); if (nextO instanceof UIContact) { contactList.addContact( new InviteUIContact((UIContact) nextO, backupProvider), null, false, false); } } return true; } else if (o instanceof UIContact) { contactList.addContact( new InviteUIContact((UIContact) o, backupProvider), null, false, false); return true; } else if (o instanceof ContactNode) { UIContact uiContact = ((ContactNode) o).getContactDescriptor(); if (uiContact != null) { contactList.addContact( new InviteUIContact(uiContact, backupProvider), null, false, false); return true; } } } return false; } /** * The backup provider to use if no provider has been specified. * * @param backupProvider the backup provider to use if no provider has been * specified */ public void setBackupProvider(ProtocolProviderService backupProvider) { this.backupProvider = backupProvider; } /** * Transferable for TreeContactList that enables drag and drop of * ui contacts. */ public class UIContactTransferable implements Transferable { /** * The ui contact. */ private final List<UIContact> uiContacts; /** * Creates an instance of <tt>UIContactTransferable</tt>. * * @param uiContacts the ui contacts to transfer */ public UIContactTransferable(List<UIContact> uiContacts) { this.uiContacts = uiContacts; } /** * Returns supported flavors. * * @return an array of supported flavors */ public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[] {uiContactDataFlavor}; } /** * Returns <tt>true</tt> if the given <tt>flavor</tt> is supported, * otherwise returns <tt>false</tt>. * * @param flavor the data flavor to verify * @return <tt>true</tt> if the given <tt>flavor</tt> is supported, * otherwise returns <tt>false</tt> */ public boolean isDataFlavorSupported(DataFlavor flavor) { return uiContactDataFlavor.equals(flavor); } /** * Returns the selected text. * * @param flavor the flavor * @return the selected text * @exception UnsupportedFlavorException if the requested data flavor * is not supported. * @exception IOException if the data is no longer available in the * requested flavor. */ public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { return uiContacts; } /** * Returns the ui contacts. * * @return the ui contacts */ public List<UIContact> getUIContacts() { return uiContacts; } } }