Package com.salas.bb.dialogs.guide

Source Code of com.salas.bb.dialogs.guide.BasicGuideDialog$Probe

// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software Foundation;
// either version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program;
// if not, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: BasicGuideDialog.java,v 1.54 2008/04/03 08:53:25 spyromus Exp $
//

package com.salas.bb.dialogs.guide;

import com.jgoodies.binding.adapter.BoundedRangeAdapter;
import com.jgoodies.binding.value.ValueHolder;
import com.jgoodies.forms.factories.ButtonBarFactory;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.uif.AbstractDialog;
import com.jgoodies.uif.util.ResourceUtils;
import com.salas.bb.core.GlobalController;
import com.salas.bb.core.actions.guide.AbstractReadingListDialog;
import com.salas.bb.dialogs.CollectionItemsSelectionDialog;
import com.salas.bb.domain.GuidesSet;
import com.salas.bb.domain.IGuide;
import com.salas.bb.domain.ReadingList;
import com.salas.bb.domain.utils.GuideIcons;
import com.salas.bb.utils.CommonUtils;
import com.salas.bb.utils.StringUtils;
import com.salas.bb.utils.TimeRange;
import com.salas.bb.utils.i18n.Strings;
import com.salas.bb.utils.uif.*;
import com.salas.bb.utils.uif.table.TooltipTableCellRenderer;
import com.salas.bb.views.mainframe.StarsSelectionComponent;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
* Basic stage for both (add / edit) guide dialogs.
*/
public abstract class BasicGuideDialog extends AbstractDialog
{
    private static final String SERVICE_LINK = "http://www.blogbridge.com/";

    /** Width of dialog box in pixels. */
    private static final int DIALOG_WIDTH = 500;

    private final boolean           publishingAvailable;
    private int                     publishingLimit;
    private boolean                 publishingLimitReached;

    private final JTable            tblReadingLists;
    private final ReadingListsTableModel readingListsModel;
    private final JButton           btnAddReadingList;
    private final JButton           btnRemoveList;

    protected JTextField            tfTitle = new JTextField();
    protected String                originalTitle = null;

    protected Collection            presentTitles;
    protected ComboBoxModel         model;
    protected IconListCellRenderer  renderer;

    protected JCheckBox             chPublishingEnabled;
    protected JLabel                lbPublishingTitle;
    protected JLabel                lbPublishingTags;
    protected JLabel                lbPublishingURL;
    protected JLabel                lbPublishingPublic;
    protected LinkLabel             lnkPublishingURL;
    protected JLabel                lbLastPublishingDate;
    protected JLabel                tfLastPublishingDate;
    protected JTextField            tfPublishingTitle;
    protected JTextField            tfPublishingTags;
    protected JCheckBox             chPublishingPublic;
    protected JLabel                lbPublishingRating;
    protected StarsSelectionComponent sscPublishingRating;
    protected ValueHolder           vhPublishingRating;
    protected JButton               btnCopyToClipboard;
    protected JCheckBox             chAllowNotifications;
    protected JCheckBox             chMobile;

    protected GuidesSet             guidesSet;

    /**
     * Creates dialog.
     *
     * @param aFrame                    parent frame.
     * @param aTitle                    dialog title.
     * @param aPublishingAvailable      <code>TRUE</code> if publishing is available.
     * @param aPublishingLimit          the number of guides the user can have published.
     * @param aPublishingLimitReached   <code>TRUE</code> if the limit is reached.
     */
    public BasicGuideDialog(Frame aFrame, String aTitle, boolean aPublishingAvailable,
                            int aPublishingLimit, boolean aPublishingLimitReached)
    {
        super(aFrame, aTitle);

        publishingAvailable = aPublishingAvailable;
        publishingLimit = aPublishingLimit;
        publishingLimitReached = aPublishingLimitReached;

        presentTitles = Collections.EMPTY_SET;
        model = new GuideIcons.ComboBoxModel();
        renderer = new IconListCellRenderer();
        readingListsModel = new ReadingListsTableModel();

        tblReadingLists = new JTable(readingListsModel);
        tblReadingLists.setDefaultRenderer(String.class, new ReadingListsTableCellRenderer(readingListsModel));
        UifUtilities.setTableColWidth(tblReadingLists, 2, 90);

        btnAddReadingList = new JButton(null, ResourceUtils.getIcon("add.icon"));
        btnAddReadingList.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                onAddReadingList();
            }
        });
        btnRemoveList = new JButton(null, ResourceUtils.getIcon("delete.icon"));
        btnRemoveList.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                onRemoveReadingList();
            }
        });

        // Publishing components
        chPublishingEnabled = ComponentsFactory.createCheckBox(Strings.message("guide.dialog.enable.publishing"));
        lbPublishingPublic = new JLabel(Strings.message("guide.dialog.public.visibility"));
        chPublishingPublic = new JCheckBox();
        lbPublishingTitle = ComponentsFactory.createLabel(Strings.message("guide.dialog.reading.list.title"));
        lbPublishingTags = ComponentsFactory.createLabel(Strings.message("guide.dialog.tags"));
        lbPublishingURL = new JLabel(Strings.message("guide.dialog.publicationurl"));
        lnkPublishingURL = new LinkLabel(Strings.message("guide.dialog.not.published.yet"));
        lbLastPublishingDate = new JLabel(Strings.message("guide.dialog.last.update.date"));
        tfLastPublishingDate = new JLabel(Strings.message("guide.dialog.never.updated"));
        tfPublishingTitle = new JTextField();
        lbPublishingTitle.setLabelFor(tfPublishingTitle);
        tfPublishingTags = new JTextField();
        lbPublishingTags.setLabelFor(tfPublishingTags);

        chMobile = ComponentsFactory.createCheckBox(Strings.message("guide.dialog.mobile"));

        vhPublishingRating = new ValueHolder(1);
        sscPublishingRating = new StarsSelectionComponent(new BoundedRangeAdapter(vhPublishingRating, 0, 1, 5));
        lbPublishingRating = new JLabel(Strings.message("guide.dialog.rating"));

        btnCopyToClipboard = new JButton(Strings.message("guide.dialog.copy"));
        btnCopyToClipboard.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                CommonUtils.copyTextToClipboard(lnkPublishingURL.getText());
            }
        });

        onPublishingEnabled();
        chPublishingEnabled.addItemListener(new ItemListener()
        {
            public void itemStateChanged(ItemEvent e)
            {
                onPublishingEnabled();
            }
        });

        chAllowNotifications = ComponentsFactory.createCheckBox(Strings.message("guide.dialog.allow.notifications"));
    }

    /**
     * Enabled / disable publishing controls depending on the state of the
     * "Enable Publishing" mark.
     */
    private void onPublishingEnabled()
    {
        boolean enabled = chPublishingEnabled.isSelected();

        lbPublishingPublic.setEnabled(enabled);
        chPublishingPublic.setEnabled(enabled);
        lbLastPublishingDate.setEnabled(enabled);
        tfLastPublishingDate.setEnabled(enabled);
        lbPublishingTags.setEnabled(enabled);
        lbPublishingTitle.setEnabled(enabled);
        lbPublishingURL.setEnabled(enabled);
        lnkPublishingURL.setEnabled(enabled);
        btnCopyToClipboard.setEnabled(enabled);
        tfPublishingTags.setEnabled(enabled);
        tfPublishingTitle.setEnabled(enabled);
        lbPublishingRating.setEnabled(enabled);
        sscPublishingRating.setEnabled(enabled);

        if (enabled && StringUtils.isEmpty(getPublishingTitle()))
        {
            tfPublishingTitle.setText(getGuideTitle());
        }
    }

    /**
     * Invoked when adding new reading list is required.
     */
    private void onAddReadingList()
    {
        if (GlobalController.SINGLETON.checkForNewSubscription()) return;

        URL[] newListURLs = queryForURL();
        if (newListURLs != null)
        {
            for (URL url : newListURLs) readingListsModel.addList(url);
        }
    }

    private URL[] queryForURL()
    {
        NewReadingListDialog dialog = new NewReadingListDialog(this);
        dialog.open();

        String urlsS = !dialog.hasBeenCanceled() ? dialog.getURLs() : null;

        return StringUtils.strToURLs(urlsS);
    }

    /**
     * Invoked when removing selected reading list is required.
     */
    private void onRemoveReadingList()
    {
        int[] rows = tblReadingLists.getSelectedRows();
        boolean haveFeeds = false;
        for (int i = 0; !haveFeeds && i < rows.length; i++)
        {
            int row = rows[i];
            haveFeeds = readingListsModel.getLists()[row].getFeeds().length > 0;
        }

        boolean delete = true;
        if (haveFeeds)
        {
            String msg = rows.length == 1
                ? Strings.message("guide.dialog.readinglists.has.feeds")
                : Strings.message("guide.dialog.readinglists.have.feeds");

            delete = JOptionPane.showConfirmDialog(this, msg, Strings.message("guide.dialog.delete.readinglist"),
                JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
        }

        if (delete) readingListsModel.removeRows(rows);
    }

    /**
     * Returns title entered by user.
     *
     * @return title.
     */
    public String getGuideTitle()
    {
        return tfTitle.getText();
    }

    /**
     * Returns <code>TRUE</code> if mobility is on.
     *
     * @return <code>TRUE</code> if mobility is on.
     */
    public boolean isMobile()
    {
        return chMobile.isSelected();
    }

    /**
     * Returns <code>TRUE</code> if publishing is enabled.
     *
     * @return <code>TRUE</code> when publishing is enabled.
     */
    public boolean isPublishingEnabled()
    {
        return chPublishingEnabled.isSelected();
    }

    /**
     * Returns the title of the reading list the user is going to publish.
     *
     * @return the title.
     */
    public String getPublishingTitle()
    {
        return tfPublishingTitle.getText().trim();
    }

    /**
     * Returns the tags of the reading list the user is going to publish.
     *
     * @return the tags.
     */
    public String getPublishingTags()
    {
        return tfPublishingTags.getText().trim();
    }

    /**
     * Returns the state of public publishing flag.
     *
     * @return the state of the flag.
     */
    public boolean isPublishingPublic()
    {
        return chPublishingPublic.isSelected();
    }

    /**
     * Returns minimum rating of feed to be published.
     *
     * @return minimum rating.
     */
    public int getPublishingRating()
    {
        return (Integer)vhPublishingRating.getValue();
    }

    /**
     * Returns resource key of selected icon.
     *
     * @return resource key.
     */
    public abstract String getIconKey();

    /**
     * Registers the list of titles which are not allowed.
     *
     * @param presTitles titles which are not allowed for entry.
     */
    protected void setPresentTitles(Collection presTitles)
    {
        this.presentTitles = presTitles;
    }

    /**
     * Returns <code>TRUE</code> when guide notifications are allowed.
     *
     * @return <code>TRUE</code> when guide notifications are allowed.
     */
    public boolean isNotificationsAllowed()
    {
        return chAllowNotifications.isSelected();
    }

    /**
     * Checks if information is valid.
     *
     * @return error message or NULL if everything is OK.
     */
    protected String validateInformation()
    {
        String msg = validateTitle();
        if (msg == null) msg = validatePublishing();

        return msg;
    }

    /**
     * Validates the publishing information entered.
     *
     * @return error message or <code>NULL</code> if everything is OK.
     */
    protected String validatePublishing()
    {
        String msg = null;

        if (isPublishingEnabled())
        {
            String publishingTitle = getPublishingTitle();
            if (StringUtils.isEmpty(publishingTitle))
            {
                msg = Strings.message("guide.dialog.validation.publishing.empty.title");
            } else if (StringUtils.indexOfAny(publishingTitle, new String[] { "/", "\"" }) > -1)
            {
                msg = Strings.message("guide.dialog.validation.publishing.invalid.title");
            } else
            {
                IGuide currentGuide = getGuide();
                IGuide otherGuide = guidesSet.getGuideByPublishingTitle(publishingTitle);

                if (currentGuide == null
                    ? otherGuide != null
                    : otherGuide != null && otherGuide != currentGuide)
                {
                    msg = MessageFormat.format(Strings.message("guide.dialog.validation.publishing.existing.title"),
                        getPublishingTitle());
                }
            }
        }

        return msg;
    }

    /**
     * The guide we are looking at.
     *
     * @return the guide.
     */
    protected abstract IGuide getGuide();

    /**
     * Checks if title is valid.
     *
     * @return error message or NULL.
     */
    protected String validateTitle()
    {
        String message = null;

        final String title = tfTitle.getText();
        if (title == null || title.trim().length() == 0)
        {
            message = Strings.message("guide.dialog.validation.empty.title");
        } else if (CommonUtils.areDifferent(originalTitle, title) && presentTitles.contains(title))
        {
            message = Strings.message("guide.dialog.validation.already.present");
        }
        return message;
    }

    /**
     * Returns test probe to the caller.
     *
     * @return test probe.
     */
    public Probe getProbe()
    {
        return new Probe();
    }

    /**
     * Called when user confirms the information.
     */
    public void doAccept()
    {
        String validationMessage = validateInformation();
        if (validationMessage == null)
        {
            super.doAccept();
        } else
        {
            JOptionPane.showMessageDialog(this, validationMessage,
                Strings.message("guide.dialog.error"),
                JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * Creates Publishing tab.
     *
     * @return component.
     */
    protected JComponent buildPublishingTab()
    {
        JComponent wording = ComponentsFactory.createWrappedMultilineLabel(
            Strings.message("guide.dialog.publishing.publish"));

        return publishingAvailable
            ? (isReachedPublishingLimit()
                ? buildPublishingTabLimitReached(wording)
                : buildPublishingTabAvailable(wording))
            : buildPublishingTabUnavailable(wording);
    }

    /**
     * Tests if the publishing limit is reached.
     *
     * @return <code>TRUE</code> if the limit has been reached and it's not the already published guide.
     */
    private boolean isReachedPublishingLimit()
    {
        return publishingLimitReached && !chPublishingEnabled.isSelected();
    }

    /**
     * Builds the panel for publishing tab when too many guides are already published.
     *
     * @param wording wording to put on the page.
     *
     * @return component.
     */
    private JPanel buildPublishingTabLimitReached(JComponent wording)
    {
        BBFormBuilder builder = new BBFormBuilder("0:grow");
        builder.setDefaultDialogBorder();

        builder.append(wording);
        builder.appendUnrelatedComponentsGapRow(2);

        builder.append(ComponentsFactory.createWrappedMultilineLabel(
            MessageFormat.format(Strings.message("guide.dialog.publishing.limit.reached"), publishingLimit)));
        builder.appendUnrelatedComponentsGapRow(2);

        LinkLabel link = new LinkLabel(Strings.message("guide.dialog.publishing.limit.reached.link"), SERVICE_LINK);
        builder.append(link);

        return builder.getPanel();
    }

    /**
     * Builds panel for publishing tab when publishing is unavailable.
     *
     * @param aWording wording to put on the page.
     *
     * @return component.
     */
    private JPanel buildPublishingTabUnavailable(JComponent aWording)
    {
        // Panel
        BBFormBuilder builder = new BBFormBuilder("0:grow");
        builder.setDefaultDialogBorder();

        builder.append(aWording);
        builder.appendUnrelatedComponentsGapRow(2);

        builder.append(ComponentsFactory.createWrappedMultilineLabel(
            Strings.message("guide.dialog.publishing.you.need.bbservice.account")));

        return builder.getPanel();
    }

    /**
     * Builds panel for publishing tab when publishing is available.
     *
     * @param aWording wording to put on the page.
     *
     * @return component.
     */
    private JPanel buildPublishingTabAvailable(JComponent aWording)
    {
        JPanel sscPanel = new JPanel(new BorderLayout());
        sscPanel.add(sscPublishingRating, BorderLayout.WEST);

        // Panel
        BBFormBuilder builder = new BBFormBuilder("7dlu, p, 2dlu, 100dlu, 0:grow, 2dlu, p");
        builder.setDefaultDialogBorder();

        builder.append(aWording, 7);
        builder.appendUnrelatedComponentsGapRow(2);

        builder.append(chMobile, 7);
        builder.append(chPublishingEnabled, 7);
        builder.setLeadingColumnOffset(1);
        builder.append(lbPublishingTitle, tfPublishingTitle);
        builder.nextLine();
        builder.append(lbPublishingTags, tfPublishingTags);
        builder.nextLine();
        builder.append(lbPublishingPublic, chPublishingPublic);
        builder.nextLine();
        builder.append(lbPublishingRating, sscPanel);
        builder.appendUnrelatedComponentsGapRow(2);

        builder.append(lbPublishingURL);
        builder.append(lnkPublishingURL, 2);
        builder.append(btnCopyToClipboard);
        builder.append(lbLastPublishingDate, tfLastPublishingDate);

        builder.setLeadingColumnOffset(0);
        builder.appendUnrelatedComponentsGapRow(2);
        builder.appendRow("min:grow");

        JComponent instructionsBox = ComponentsFactory.createInstructionsBox(
            Strings.message("guide.dialog.publishing.instructions"));
        builder.append(instructionsBox, 7, CellConstraints.FILL, CellConstraints.FILL);

        return builder.getPanel();
    }

    private JComponent msg(String msg)
    {
        return ComponentsFactory.createWrappedMultilineLabel(msg);
    }

    /**
     * Creates notifications panel.
     *
     * @return panel.
     */
    protected JComponent buildNotificationsTab()
    {
        // Wording
        JComponent wording = msg(Strings.message("guide.dialog.notifications.wording"));

        // Panel
        BBFormBuilder builder = new BBFormBuilder("0:grow");
        builder.setDefaultDialogBorder();

        builder.append(wording);
        builder.appendUnrelatedComponentsGapRow(2);
        builder.append(chAllowNotifications);

        return builder.getPanel();
    }

    /**
     * Builds reading lists tab.
     *
     * @return component.
     */
    protected JComponent buildReadingListsTab()
    {
        // Wording
        JComponent wording = msg(Strings.message("guide.dialog.readinglists.wording"));

        // Buttons
        Dimension btnSize = new Dimension(20, 20);
        btnAddReadingList.setPreferredSize(btnSize);
        btnRemoveList.setPreferredSize(btnSize);
        FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
        JPanel bbar = new JPanel(layout);
        bbar.add(btnAddReadingList);
        bbar.add(btnRemoveList);
        layout.setHgap(0);
        layout.setVgap(0);

        // Panel
        BBFormBuilder builder = new BBFormBuilder("0:grow");
        builder.setDefaultDialogBorder();

        builder.append(wording);
        builder.appendUnrelatedComponentsGapRow(2);
        builder.appendRow("min:grow");
        builder.append(new JScrollPane(tblReadingLists), 1,
            CellConstraints.FILL, CellConstraints.FILL);
        builder.append(bbar);

        return builder.getPanel();
    }

    /**
     * Shows given list of reading lists.
     *
     * @param lists lists.
     */
    protected void setReadingLists(ReadingList[] lists)
    {
        tblReadingLists.setEnabled(lists != null);
        btnAddReadingList.setEnabled(lists != null);
        btnRemoveList.setEnabled(lists != null);

        readingListsModel.setLists(lists);
    }

    /**
     * Returns currently displayed list of reading lists.
     *
     * @return list which is currently displayed.
     */
    public ReadingList[] getReadingLists()
    {
        return readingListsModel.getLists();
    }

    protected void resizeHook(JComponent content)
    {
        int height = (int)(DIALOG_WIDTH * 1.1);
        content.setPreferredSize(new Dimension(DIALOG_WIDTH, height));
    }

    /**
     * Opens a dialog.
     *
     * @param set guides set.
     */
    public void openDialog(GuidesSet set)
    {
        guidesSet = set;
        super.open();
    }

    /**
     * Renders simple icon element basing on the key of resource passed in <code>value</code>
     * parameter as a String.
     */
    protected static class IconListCellRenderer extends JPanel
            implements ListCellRenderer
    {
        private JLabel iconLabel = new JLabel();

        /**
         * Constructs new cell renderer.
         */
        public IconListCellRenderer()
        {
            add(iconLabel);
        }

        /**
         * Return a component that has been configured to display the specified
         * value.
         *
         * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList,
         *      Object, int, boolean, boolean)
         */
        public Component getListCellRendererComponent(JList list, Object value, int index,
                                                      boolean isSelected, boolean cellHasFocus)
        {
            final String key = (String)value;
            final Icon icon = IconSource.getIcon(key);

            final Color back = isSelected ? list.getSelectionBackground() : list.getBackground();
            setBackground(back);
            iconLabel.setBackground(back);

            iconLabel.setIcon(icon);

            return this;
        }
    }

    /**
     * Cell renderer that makes missing reading lists appear gray.
     */
    private static class ReadingListsTableCellRenderer extends TooltipTableCellRenderer
    {
        private final ReadingListsTableModel model;

        /**
         * Creates cell renderer.
         *
         * @param model model.
         */
        public ReadingListsTableCellRenderer(ReadingListsTableModel model)
        {
            this.model = model;
        }

        /**
         * Returns the default table cell renderer.
         *
         * @param table      the <code>JTable</code>
         * @param value      the value to assign to the cell at
         *                   <code>[row, column]</code>
         * @param isSelected true if cell is selected
         * @param hasFocus   true if cell has focus
         * @param row        the row of the cell to render
         * @param column     the column of the cell to render
         * @return the default table cell renderer
         */
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                                                       boolean hasFocus, int row, int column)
        {
            ReadingList list = model.getLists()[row];
            Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            comp.setForeground(list.isMissing() ? Color.GRAY : table.getForeground());
            return comp;
        }
    }

    /**
     * Reading lists table model.
     */
    private static class ReadingListsTableModel extends DefaultTableModel
    {
        // Format for dates
        private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("EEE MMM dd, yy");

        /** List name. */
        public static final int COL_NAME    = 0;
        /** List URL. */
        public static final int COL_URL     = 1;
        /** List latest update time. */
        public static final int COL_LATEST  = 2;

        private static final String[] COLUMNS = {
            Strings.message("guide.dialog.readinglists.table.name"),
            Strings.message("guide.dialog.readinglists.table.url"),
            Strings.message("guide.dialog.readinglists.table.latest")
        };
        private static final Class[] CLASSES = { String.class, String.class, String.class };

        private ReadingList[] lists;

        /**
         * Returns current version of reading lists.
         *
         * @return current version.
         */
        public ReadingList[] getLists()
        {
            return lists;
        }

        /**
         * Sets the version of reading lists.
         *
         * @param aLists lists.
         */
        public void setLists(ReadingList[] aLists)
        {
            lists = aLists;
            fireTableDataChanged();
        }

        /**
         * Returns number of columns in this table.
         *
         * @return columns
         */
        public int getColumnCount()
        {
            return COLUMNS.length;
        }

        /**
         * Returns number of rows in the table.
         *
         * @return rows.
         */
        public int getRowCount()
        {
            return lists == null ? 0 : lists.length;
        }

        /**
         * Returns value of a cell.
         *
         * @param row       row.
         * @param column    column.
         *
         * @return value.
         */
        public Object getValueAt(int row, int column)
        {
            Object value;
            ReadingList list = lists[row];

            switch (column)
            {
                case COL_NAME:
                    value = list.getTitle();
                    break;
                case COL_URL:
                    value = list.getURL().toString();
                    break;
                case COL_LATEST:
                    long lastPollTime = list.getLastPollTime();
                    value = pollTimeToString(lastPollTime);
                    break;
                default:
                    value = null;
            }
            return value;
        }

        /**
         * Converts timestamp into some string representation.
         *
         * @param aTime time to convert.
         *
         * @return string.
         */
        private String pollTimeToString(long aTime)
        {
            String timeS;

            if (aTime == -1)
            {
                timeS = Strings.message("guide.dialog.readinglists.table.latest.never");
            } else
            {
                TimeRange range = findTimeRange(aTime);
                if (range == TimeRange.TR_FUTURE)
                {
                    timeS = Strings.message("guide.dialog.readinglists.table.latest.never");
                } else if (range == TimeRange.TR_TODAY)
                {
                    DateFormat fmt = DateFormat.getTimeInstance(DateFormat.SHORT);
                    timeS = MessageFormat.format(Strings.message("guide.dialog.readinglists.table.latest.today.0"),
                        fmt.format(new Date(aTime)));
                } else if (range == TimeRange.TR_YESTERDAY)
                {
                    DateFormat fmt = DateFormat.getTimeInstance(DateFormat.SHORT);
                    timeS = MessageFormat.format(Strings.message("guide.dialog.readinglists.table.latest.yesterday.0"),
                        fmt.format(new Date(aTime)));
                } else
                {
                    timeS = DATE_FORMAT.format(new Date(aTime));
                }
            }

            return timeS;
        }

        /**
         * Finds range matching this time.
         *
         * @param aTime time.
         *
         * @return range.
         */
        private TimeRange findTimeRange(long aTime)
        {
            TimeRange range = null;

            for (int i = 0; range == null && i < TimeRange.TIME_RANGES.length; i++)
            {
                TimeRange timeRange = TimeRange.TIME_RANGES[i];
                if (timeRange.isInRange(aTime)) range = timeRange;
            }

            return range;
        }

        /**
         * None of the cells editable.
         *
         * @param row       row.
         * @param column    column.
         *
         * @return <code>FALSE</code>.
         */
        public boolean isCellEditable(int row, int column)
        {
            return false;
        }

        /**
         * Returns the title of the column.
         *
         * @param column column.
         *
         * @return title.
         */
        public String getColumnName(int column)
        {
            return COLUMNS[column];
        }

        /**
         * Returns data class of the column.
         *
         * @param column column.
         *
         * @return class.
         */
        public Class getColumnClass(int column)
        {
            return CLASSES[column];
        }

        /**
         * Removes specific rows from the list of reading lists.
         *
         * @param aRows rows to remove.
         */
        public void removeRows(int[] aRows)
        {
            Arrays.sort(aRows);

            java.util.List<ReadingList> newLists = new ArrayList<ReadingList>(Arrays.asList(lists));
            for (int i = aRows.length - 1; i >= 0; i--)
            {
                newLists.remove(aRows[i]);
            }

            setLists(newLists.toArray(new ReadingList[newLists.size()]));
        }

        /**
         * Adds new reading list URL.
         *
         * @param aNewListURL new reading list.
         */
        public void addList(URL aNewListURL)
        {
            ReadingList[] newList = new ReadingList[lists.length + 1];
            System.arraycopy(lists, 0, newList, 0, lists.length);
            newList[lists.length] = new ReadingList(aNewListURL);

            setLists(newList);
        }
    }

    /**
     * New reading list addition dialog with verification of URL.
     */
    private class NewReadingListDialog extends AbstractReadingListDialog
    {
        private final JButton btnSuggest;

        /**
         * Creates dialog.
         *
         * @param parent parent dialog.
         */
        public NewReadingListDialog(Dialog parent)
        {
            super(parent, Strings.message("guide.dialog.add.readinglist"));

            btnSuggest = new JButton(new SuggestAction());
            enableEvents(AWTEvent.WINDOW_EVENT_MASK);
        }

        /**
         * Repacks the window each time it is displayed to adjust size to fit
         * wording and buttons.
         *
         * @param e event.
         */
        protected void processWindowEvent(WindowEvent e)
        {
            super.processWindowEvent(e);

            if (e.getID() == WindowEvent.WINDOW_OPENED) pack();
        }

        /**
         * Builds main part.
         *
         * @return main part.
         */
        protected JComponent buildMain()
        {
            BBFormBuilder builder = new BBFormBuilder("pref, 4dlu, max(pref;200px):grow, 4dlu, p");
            builder.setDefaultDialogBorder();

            JComponent wording = ComponentsFactory.createWrappedMultilineLabel(
                Strings.message("guide.dialog.readinglists.add.wording"));

            builder.append(wording, 3);
            builder.appendUnrelatedComponentsGapRow(2);

            builder.append(Strings.message("guide.dialog.readinglists.add.address"), tfAddress);
            builder.append(btnSuggest);
            builder.append(Strings.message("guide.dialog.readinglists.add.status"), lbStatus);

            return builder.getPanel();
        }

        /**
         * Builds buttons.
         *
         * @return buttons.
         */
        protected JComponent buildButtons()
        {
            return ButtonBarFactory.buildOKCancelBar(btnCheckAndAdd, createCancelButton());
        }

        private class SuggestAction extends AbstractAction
        {
            /**
             * Defines an <code>Action</code> object with a default
             * description string and default icon.
             */
            public SuggestAction()
            {
                super(Strings.message("guide.dialog.readinglists.add.suggest"));
            }

            /**
             * Invoked when an action occurs.
             */
            public void actionPerformed(ActionEvent e)
            {
                CollectionItemsSelectionDialog dialog =
                        new CollectionItemsSelectionDialog(BasicGuideDialog.this);

                tfAddress.setText(dialog.open("", new ArrayList(), true));
                if (!dialog.hasBeenCanceled()) NewReadingListDialog.super.doAccept();
            }
        }
    }

    /**
     * Testing agent used in tests.
     */
    public class Probe
    {
        /**
         * Initializes structured and values necessary for title validation.
         *
         * @param orgTitle original title (NULL for new guide).
         * @param prTitles list of present titles.
         * @param title    title entered by user.
         *
         * @return TRUE if validation was successful.
         */
        public boolean validate(String orgTitle, Collection prTitles, String title)
        {
            originalTitle = orgTitle;
            setPresentTitles(prTitles);
            tfTitle.setText(title);

            return validateInformation() == null;
        }
    }
}
TOP

Related Classes of com.salas.bb.dialogs.guide.BasicGuideDialog$Probe

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.