/** * Copyright (c) 2005-2017, KoLmafia development team * http://kolmafia.sourceforge.net/ * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * [1] Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * [2] Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * [3] Neither the name "KoLmafia" nor the names of its contributors may * be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package net.sourceforge.kolmafia.swingui; import com.sun.java.forums.SpringUtilities; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.SpringLayout; import javax.swing.SwingConstants; import net.java.dev.spellcast.utilities.JComponentUtilities; import net.java.dev.spellcast.utilities.LockableListModel; import net.java.dev.spellcast.utilities.LockableListModel.ListElementFilter; import net.java.dev.spellcast.utilities.SortedListModel; import net.sourceforge.kolmafia.AdventureResult; import net.sourceforge.kolmafia.KoLConstants; import net.sourceforge.kolmafia.KoLGUIConstants; import net.sourceforge.kolmafia.persistence.ItemDatabase; import net.sourceforge.kolmafia.session.ContactManager; import net.sourceforge.kolmafia.swingui.button.InvocationButton; import net.sourceforge.kolmafia.swingui.widget.AutoFilterComboBox; import net.sourceforge.kolmafia.swingui.widget.AutoHighlightTextField; import net.sourceforge.kolmafia.swingui.widget.GenericScrollPane; import net.sourceforge.kolmafia.textui.command.SendMessageCommand; import net.sourceforge.kolmafia.utilities.InputFieldUtilities; public class SendMessageFrame extends GenericFrame implements ListElementFilter { private boolean isStorage = false; private final JComboBox sourceSelect; private final LockableListModel contacts; private final AutoFilterComboBox recipientEntry; private final LockableListModel attachments; private final JList attachmentsList; private final AutoHighlightTextField attachedMeat; private final JTextArea messageEntry; public SendMessageFrame( final String recipient ) { this(); this.setRecipient( recipient ); } public SendMessageFrame( final String recipient, final String text ) { this(); this.setRecipient( recipient ); this.setMessageText( text ); } public SendMessageFrame() { super( "Send a Message" ); JPanel mainPanel = new JPanel( new SpringLayout() ); // What kind of package you want to send. this.sourceSelect = new JComboBox(); this.sourceSelect.addItem( "Send items/meat from inventory" ); this.sourceSelect.addItem( "Send items/meat from ancestral storage" ); this.sourceSelect.addActionListener( new AttachmentClearListener() ); // Who you want to send it to. this.contacts = (LockableListModel) ContactManager.getMailContacts().getMirrorImage(); this.recipientEntry = new AutoFilterComboBox( this.contacts, true ); // How much you want to attach, in raw terms. this.attachments = new LockableListModel(); this.attachedMeat = new AutoHighlightTextField( "0" ); // Now, layout the center part of the panel. mainPanel.add( new JLabel( "Source: ", SwingConstants.RIGHT ) ); mainPanel.add( this.sourceSelect ); mainPanel.add( new JLabel( "Recipient: ", SwingConstants.RIGHT ) ); mainPanel.add( this.recipientEntry ); mainPanel.add( new JLabel( "Send Meat: ", SwingConstants.RIGHT ) ); mainPanel.add( this.attachedMeat ); SpringUtilities.makeCompactGrid( mainPanel, 3, 2, 5, 5, 5, 5 ); // Construct the east container. JButton attach = new InvocationButton( "Attach an item", "icon_plus.gif", this, "attachItem" ); JComponentUtilities.setComponentSize( attach, 15, 15 ); JButton detach = new InvocationButton( "Remove selected items", "icon_minus.gif", this, "detachItems" ); JComponentUtilities.setComponentSize( detach, 15, 15 ); JPanel buttonPanel = new JPanel( new GridLayout( 1, 2, 0, 0 ) ); buttonPanel.add( attach ); buttonPanel.add( detach ); JPanel labelPanel = new JPanel( new BorderLayout( 5, 5 ) ); labelPanel.add( buttonPanel, BorderLayout.WEST ); labelPanel.add( new JLabel( "Attach or detach items", SwingConstants.LEFT ), BorderLayout.CENTER ); GenericScrollPane pane = new GenericScrollPane( this.attachments, 3 ); this.attachmentsList = (JList) pane.getComponent(); this.attachmentsList.addKeyListener( new RemoveAttachmentListener() ); JPanel attachPanel = new JPanel( new BorderLayout( 5, 5 ) ); attachPanel.add( labelPanel, BorderLayout.NORTH ); attachPanel.add( pane, BorderLayout.CENTER ); JPanel northPanel = new JPanel( new BorderLayout( 20, 20 ) ); northPanel.add( mainPanel, BorderLayout.CENTER ); northPanel.add( attachPanel, BorderLayout.EAST ); JPanel mainHolder = new JPanel( new BorderLayout( 20, 20 ) ); mainHolder.add( northPanel, BorderLayout.NORTH ); // Add the message entry to the panel. this.messageEntry = new JTextArea(); this.messageEntry.setFont( KoLGUIConstants.DEFAULT_FONT ); this.messageEntry.setRows( 7 ); this.messageEntry.setLineWrap( true ); this.messageEntry.setWrapStyleWord( true ); GenericScrollPane scrollArea = new GenericScrollPane( this.messageEntry ); mainHolder.add( scrollArea, BorderLayout.CENTER ); // Add a button to the bottom panel. JPanel sendPanel = new JPanel(); sendPanel.add( new InvocationButton( "send message", this, "sendMessage" ) ); mainHolder.add( sendPanel, BorderLayout.SOUTH ); // Layout the major container. JPanel cardPanel = new JPanel( new CardLayout( 10, 10 ) ); cardPanel.add( mainHolder, "" ); this.setCenterComponent( mainHolder ); } public void createItemAttachPanel() { } public void createMessagePanel() { } public void createRecipientPanel() { } public void setRecipient( String recipient ) { this.isStorage = false; this.sourceSelect.setSelectedIndex( 0 ); if ( !this.contacts.contains( recipient ) ) { recipient = ContactManager.getPlayerName( recipient ); this.contacts.add( 0, recipient ); } this.recipientEntry.getEditor().setItem( recipient ); this.recipientEntry.setSelectedItem( recipient ); this.attachments.clear(); this.attachedMeat.setText( "" ); this.messageEntry.setText( "" ); } public void setMessageText( String text ) { this.messageEntry.setText( text ); } @Override public boolean shouldAddStatusBar() { return true; } private class AttachmentClearListener implements ActionListener { public void actionPerformed( final ActionEvent e ) { boolean wasStorage = SendMessageFrame.this.isStorage; SendMessageFrame.this.isStorage = SendMessageFrame.this.sourceSelect.getSelectedIndex() == 1; if ( SendMessageFrame.this.isStorage != wasStorage ) { SendMessageFrame.this.attachments.clear(); } } } public void sendMessage() { AdventureResult[] attachmentsArray = new AdventureResult[ this.attachments.size() + 1 ]; attachmentsArray = (AdventureResult[])this.attachments.toArray( attachmentsArray ); attachmentsArray[ this.attachments.size() ] = new AdventureResult( AdventureResult.MEAT, InputFieldUtilities.getValue( this.attachedMeat, 0 ) ); String[] recipients = ContactManager.extractTargets( (String) this.recipientEntry.getSelectedItem() ); for ( int i = 0; i < recipients.length; ++i ) { SendMessageCommand.send( recipients[ i ], this.messageEntry.getText(), attachmentsArray, this.isStorage, false ); } } public boolean isVisible( Object o ) { if ( !( o instanceof AdventureResult ) ) { return false; } AdventureResult ar = (AdventureResult) o; if ( !( ar.isItem() ) ) { return false; } return ItemDatabase.isGiftable( ar.getItemId() ); } public void attachItem() { LockableListModel source = this.isStorage ? (SortedListModel) KoLConstants.storage : (SortedListModel) KoLConstants.inventory; if ( source.isEmpty() ) { return; } source = source.getMirrorImage(); int tradeableItemCount = source.getSize(); AdventureResult current; Object[] values = InputFieldUtilities.multiple( "What would you like to send?", source, this ); if ( values.length < tradeableItemCount ) { for ( int i = 0; i < values.length; ++i ) { current = (AdventureResult) values[ i ]; Integer value = InputFieldUtilities.getQuantity( "How many " + current.getName() + " to send?", current.getCount() ); int amount = ( value == null ) ? 0 : value.intValue(); if ( amount <= 0 ) { values[ i ] = null; } else { values[ i ] = current.getInstance( amount ); } } } for ( int i = 0; i < values.length; ++i ) { if ( values[ i ] != null ) { this.attachments.add( values[ i ] ); } } } public void detachItems() { JList list = this.attachmentsList; int [] indices = list.getSelectedIndices(); for ( int i = indices.length; i > 0; --i ) { int index = indices[ i - 1 ]; this.attachments.remove( index ); } } private class RemoveAttachmentListener extends KeyAdapter { @Override public void keyReleased( final KeyEvent e ) { if ( e.isConsumed() ) { return; } if ( e.getKeyCode() != KeyEvent.VK_DELETE && e.getKeyCode() != KeyEvent.VK_BACK_SPACE ) { return; } SendMessageFrame.this.detachItems(); e.consume(); } } }