Package com.rim.samples.device.blackberrymaildemo

Source Code of com.rim.samples.device.blackberrymaildemo.ComposeScreen$AddHeaderFieldAction

/*
* ComposeScreen.java
*
* Copyright � 1998-2011 Research In Motion Limited
*
* 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.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings.  However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies.  For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/

package com.rim.samples.device.blackberrymaildemo;

import java.util.Calendar;
import java.util.Vector;

import net.rim.blackberry.api.mail.Address;
import net.rim.blackberry.api.mail.AddressException;
import net.rim.blackberry.api.mail.Folder;
import net.rim.blackberry.api.mail.Message;
import net.rim.blackberry.api.mail.MessagingException;
import net.rim.blackberry.api.mail.Multipart;
import net.rim.blackberry.api.mail.Session;
import net.rim.blackberry.api.mail.Store;
import net.rim.blackberry.api.mail.TextBodyPart;
import net.rim.blackberry.api.mail.Transport;
import net.rim.device.api.command.Command;
import net.rim.device.api.command.CommandHandler;
import net.rim.device.api.command.ReadOnlyCommandMetadata;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BasicEditField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.EditField;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.component.TextField;
import net.rim.device.api.util.StringProvider;

/**
* The ComposeScreen is a screen which displays either a new or saved message.
* It adds the functionality of saving and sending messages to its parent class,
* MessageScreen.
*/
public final class ComposeScreen extends MessageScreen {
    private static final int FIRST = 0;
    private static final int SEND_MENU_ITEM_INDEX = 0;

    private final Store _store;

    /**
     * Creates a new ComposeScreen object
     *
     * @param message
     *            A message in the process of being composed, or null if a new
     *            message is to be composed
     * @param store
     *            The message store for this application
     */
    public ComposeScreen(final Message message, final Store store) {
        super(message, true);

        _store = store;

        // If a new message is to be created, indicate this in the title
        if (message == null) {
            setTitle("New Message");
        }

        // Create and add menu items specific to the Compose action (addTo,
        // addBcc, addCc, etc...).
        final AddHeaderFieldAction addToMenuItem =
                new AddHeaderFieldAction(Message.RecipientType.TO, "Add To: ",
                        "To: ");
        final AddHeaderFieldAction addCcMenuItem =
                new AddHeaderFieldAction(Message.RecipientType.CC, "Add Cc: ",
                        "Cc: ");
        final AddHeaderFieldAction addBccMenuItem =
                new AddHeaderFieldAction(Message.RecipientType.BCC,
                        "Add Bcc: ", "Bcc: ");

        // MenuItem to save a message
        final MenuItem saveMenuItem =
                new MenuItem(new StringProvider("Save Message"), 0x230020, 1);
        saveMenuItem.setCommand(new Command(new CommandHandler() {
            /**
             * @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
             *      Object)
             */
            public void execute(final ReadOnlyCommandMetadata metadata,
                    final Object context) { // If the save is completed, then
                                            // discard this screen
                if (onSave()) {
                    close();
                } else
                // If the message could not be saved, alert the user
                {
                    UiApplication.getUiApplication().invokeLater(
                            new Runnable() {
                                public void run() {
                                    Dialog.alert("Message could not be saved");
                                }
                            });
                }
            }
        }));

        // MenuItem to send a message
        final MenuItem sendMenuItem =
                new MenuItem(new StringProvider("Send Message"), 0x230010, 0);
        sendMenuItem.setCommand(new Command(new CommandHandler() {
            /**
             * @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
             *      Object)
             */
            public void execute(final ReadOnlyCommandMetadata metadata,
                    final Object context) { // If the save is completed, then
                                            // discard this screen
                try {
                    _message = getMessage();
                    if (_message != null) {
                        // Send the message
                        Transport.send(_message);

                        // Close the screen
                        close();
                    }
                } catch (final MessagingException e) {
                    BlackBerryMailDemo
                            .errorDialog("Transport.send(Message) threw "
                                    + e.toString());
                }
            }
        }));

        addMenuItem(sendMenuItem);
        addMenuItem(saveMenuItem);
        addMenuItem(addToMenuItem);
        addMenuItem(addCcMenuItem);
        addMenuItem(addBccMenuItem);
    }

    /**
     * Overrides MessageScreen.displayMessage(). The message's 'sent' properties
     * are not displayed since the message is still in the process of editing.
     */
    void displayMessage() {
        // If the message does not exist then compose a new message
        if (_message == null) {
            // Add a To line
            final EditField toField =
                    new EditField("To: ", "", 40, BasicEditField.FILTER_EMAIL);
            addTextFieldToTableAndScreen(toField, Message.RecipientType.TO);

            // Add a subject line
            final EditField subjectField = new EditField("Subject: ", "");
            addTextFieldToTableAndScreen(subjectField, SUBJECT);

            // Add a separator between the body and the headers
            add(new SeparatorField());

            // Add a body field
            final EditField bodyField = new EditField();
            addTextFieldToTableAndScreen(bodyField, BODY);
        } else
        // The message exists so display it
        {
            displayHeader();
            add(new SeparatorField());
            displayMessageBody();
        }
    }

    /**
     * Gets a message for sending or saving
     *
     * @return A new message
     */
    Message getMessage() {
        // Find an outbox folder and use it to construct a new message
        final Folder outbox = _store.findFolder("Outbox")[FIRST];
        final Message message = new Message(outbox);

        // Add all the current headers
        for (int keyNo = 0; keyNo < HEADER_KEYS.length; keyNo++) {
            final Vector fieldsByType =
                    (Vector) _fieldTable.get(HEADER_KEYS[keyNo]);

            if (fieldsByType != null) {
                // Build a vector of all the addresses
                final Vector addressVector = new Vector();
                final int size = fieldsByType.size();
                for (int fieldNo = 0; fieldNo < size; fieldNo++) {
                    final TextField addressField =
                            (TextField) fieldsByType.elementAt(fieldNo);

                    // Try to create a new address object wrapping the email
                    // address and add it to the address vector.
                    try {
                        addressVector.addElement(new Address(addressField
                                .getText(), ""));
                    } catch (final AddressException e) // Invalid address
                    {
                        BlackBerryMailDemo
                                .errorDialog("Address(String, String) threw "
                                        + e.toString());
                    }
                }

                // Dump the vector of addresses into an array to send the
                // message
                final Address[] addresses = new Address[addressVector.size()];
                addressVector.copyInto(addresses);

                // Try to add the addresses to the message's list of recipients
                try {
                    message.addRecipients(HEADER_KEYS[keyNo], addresses);
                } catch (final MessagingException e) {
                    BlackBerryMailDemo
                            .errorDialog("Message#addRecipients(int, Address[]) threw "
                                    + e.toString());
                }
            }
        }

        // Add the subject
        final Vector subjectFields = (Vector) _fieldTable.get(SUBJECT);
        final TextField subjectField =
                (TextField) subjectFields.elementAt(FIRST);

        if (subjectFields != null && subjectFields.size() > 0) {
            message.setSubject(subjectField.getText());
        }

        // Add the body by adding all the body fields into one multipart
        final Vector bodyFields = (Vector) _fieldTable.get(BODY);
        if (bodyFields != null) {
            final int size = bodyFields.size();
            final Multipart content = new Multipart();
            for (int fieldNo = 0; fieldNo < size; fieldNo++) {
                final TextField body =
                        (TextField) bodyFields.elementAt(fieldNo);
                content.addBodyPart(new TextBodyPart(content, body.getText()));
            }
            try {
                message.setContent(content);
            } catch (final MessagingException e) {
                BlackBerryMailDemo
                        .errorDialog("Message#setContent(Object) threw "
                                + e.toString());
            }
        } else {
            BlackBerryMailDemo.errorDialog("Error: no body field available");
            return null;
        }

        // Set the date
        message.setSentDate(Calendar.getInstance().getTime());

        return message;
    }

    /**
     * @see net.rim.device.api.ui.Screen#onSave()
     */
    protected boolean onSave() {
        // Save the message to the outbox
        try {
            final Message newMessage = getMessage();
            if (newMessage != null) {
                // Retrieve an outbox to save the message in
                final Store store = Session.waitForDefaultSession().getStore();
                final Folder[] allOutboxFolders = store.list(Folder.OUTBOX);

                Folder outbox = null;
                for (int i = allOutboxFolders.length - 1; i >= 0; --i) {
                    final Folder parent = allOutboxFolders[i].getParent();
                    if (parent != null
                            && parent.getName().startsWith("Mailbox")) {
                        outbox = allOutboxFolders[i];
                        break;
                    }
                }

                if (outbox == null) {
                    throw new MessagingException("no outbox folder found");
                }

                // Save the new message and replace the old one if it exists
                outbox.appendMessage(newMessage);
                if (_message != null) {
                    outbox.deleteMessage(_message, true);
                }
                _message = newMessage;

                // Set the status to composing and flag that it has been saved
                _message.setStatus(Message.Status.TX_COMPOSING,
                        Message.Status.TX_ERROR);
                _message.setFlag(Message.Flag.SAVED, true);

                return true;
            }

            return false;
        } catch (final MessagingException e) {
            return false;
        }
    }

    /**
     * Make "Send" the default menu item.
     *
     * @see net.rim.device.api.ui.container.MainScreen#makeMenu(Menu,int)
     */
    protected void makeMenu(final Menu menu, final int instance) {
        super.makeMenu(menu, instance);

        menu.setDefault(SEND_MENU_ITEM_INDEX);
    }

    /**
     * This class is responsible for adding the various header fields to the
     * compose screen (To, Bcc, CC).
     */
    private final class AddHeaderFieldAction extends MenuItem {
        private final String _fieldLabelText;
        private final int _headerType;

        /**
         * Constructs a menu item which adds a header of a specified type to the
         * compose screen.
         *
         * @param headerType
         *            One of the Message.RecipientType fields
         * @param menuItemText
         *            String to use for the menu item
         * @param fieldLabelText
         *            String to use for the label of this field
         */
        AddHeaderFieldAction(final int headerType, final String menuItemText,
                final String fieldLabelText) {
            super(new StringProvider(menuItemText), 0x240010, 2);

            _fieldLabelText = fieldLabelText;
            _headerType = headerType;
            this.setCommand(new Command(new CommandHandler() {
                /**
                 * Adds a new header field to the message. The field is placed
                 * so that the header types are grouped together and the most
                 * recently added one is closest to the bottom.
                 *
                 * @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
                 *      Object)
                 */
                public void execute(final ReadOnlyCommandMetadata metadata,
                        final Object context) {
                    final EditField newField =
                            new EditField(_fieldLabelText, "");

                    // Find out where the last field of this type was added to
                    // the
                    // screen.
                    Vector fieldsByType = (Vector) _fieldTable.get(_headerType);
                    int lastInsertedIndex;
                    if (fieldsByType == null) {
                        // If a field of _headerType was not made yet, then
                        // create the
                        // vector which contains all of the fields of
                        // _headerType.
                        fieldsByType = new Vector();
                        _fieldTable.put(_headerType, fieldsByType);
                        lastInsertedIndex = getIndexForNewFieldType();
                    } else {
                        lastInsertedIndex =
                                getIndexOfLastFieldOfType(_headerType);
                    }

                    // Add the new field to both the screen and the vector
                    // keeping track
                    // of all the fields of the same type.
                    ComposeScreen.this.insert(newField, lastInsertedIndex + 1);
                    fieldsByType.addElement(newField);
                    newField.setFocus();
                }
            }));
        }

        /**
         * Given the existing field type of this instance of the class,
         * determine where to place new header fields in the screen.
         *
         * @return The index at which to insert the new header field
         */
        private int getIndexForNewFieldType() {
            // Note: we don't handle TO here since there ALWAYS must be one TO
            // field.
            switch (_headerType) {
            // Find the last TO field and use the next index as the
            // insertion point.
            case Message.RecipientType.CC:
                return getIndexOfLastFieldOfType(Message.RecipientType.TO);

                // Try to find the last CC field and use it as the next
                // insertion point. If no CC field exists then find the last
                // TO field and use its index as the insertion point.
            case Message.RecipientType.BCC:
                final int index =
                        getIndexOfLastFieldOfType(Message.RecipientType.CC);
                if (index == -1) {
                    return getIndexOfLastFieldOfType(Message.RecipientType.TO);
                }
                return index;

            default:
                throw new IllegalStateException(
                        "Mail Demo: Unrecognized recipient type");
            }
        }

        /**
         * Retrieves the index of the last field added of a specified type.
         *
         * @param type
         *            The type of header field to retrieve the last index of
         * @return The index of the most recently added field of the specified
         *         type, -1 if a field of the specified type has not been added
         *         yet.
         */
        private int getIndexOfLastFieldOfType(final int type) {
            final Vector fields = (Vector) _fieldTable.get(type);
            if (fields == null) {
                return -1;
            }

            final Field field = (Field) fields.lastElement();

            return field.getIndex();
        }
    }
}
TOP

Related Classes of com.rim.samples.device.blackberrymaildemo.ComposeScreen$AddHeaderFieldAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.