Package com.salas.bb.remixfeeds.prefs

Source Code of com.salas.bb.remixfeeds.prefs.BlogDetailsPreferencesPanel$WeblogTypeChangeListener

// 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: BlogDetailsPreferencesPanel.java,v 1.28 2008/06/26 13:41:58 spyromus Exp $
//

package com.salas.bb.remixfeeds.prefs;

import com.jgoodies.binding.adapter.ComboBoxAdapter;
import com.jgoodies.binding.adapter.DocumentAdapter;
import com.jgoodies.binding.adapter.RadioButtonAdapter;
import com.jgoodies.binding.beans.PropertyAdapter;
import com.jgoodies.binding.list.ArrayListModel;
import com.jgoodies.binding.value.AbstractConverter;
import com.jgoodies.binding.value.BufferedValueModel;
import com.jgoodies.binding.value.Trigger;
import com.jgoodies.binding.value.ValueModel;
import com.jgoodies.forms.builder.ButtonBarBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.uif.AbstractDialog;
import com.salas.bb.remixfeeds.api.IWeblogAPI;
import com.salas.bb.remixfeeds.api.WeblogAPIs;
import com.salas.bb.remixfeeds.templates.Editor;
import com.salas.bb.remixfeeds.templates.Templates;
import com.salas.bb.utils.Constants;
import com.salas.bb.utils.StringUtils;
import com.salas.bb.utils.i18n.Strings;
import com.salas.bb.utils.uif.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;

/**
* Single blog details panel.
*/
class BlogDetailsPreferencesPanel extends JPanel implements PropertyChangeListener
{
    private JDialog parent;

    private final TargetBlogProxy proxy = new TargetBlogProxy(null);

    public static final String PROP_BLOG_PREFERENCES = "blogPreferences";

    private Trigger trigger             = new Trigger();
    private JTextField tfTitle          = new JTextField();
    private JTextField tfURLSummary     = new JTextField();
    private JTextField tfURL            = new JTextField();
    private JTextField tfUser           = new JTextField();
    private JPasswordField tfPassword   = new JPasswordField();
    private JTextArea  taDescription    = new JTextArea();
    private JComboBox cbDefaultCategory = new JComboBox();
    private JComboBox cbBlog            = new JComboBox();
    private JComboBox cbWeblogAPIType;

    private FetchBlogsAction actFetchBlogs;
    private FetchCategoriesAction actFetchCategories;

    private JButton btnSetup;
    private JButton btnFetchCategories;
    private JButton btnFetchBlogs;

    private JRadioButton rbPublic               = new JRadioButton(Strings.message("ptb.prefs.public"));
    private JRadioButton rbDraft                = new JRadioButton(Strings.message("ptb.prefs.draft"));

    private final JLabel lbTitle                = new JLabel(Strings.message("ptb.prefs.details.name"));
    private final JLabel lbURL                  = new JLabel(Strings.message("ptb.prefs.details.url"));
    private final JLabel lbDefaultCategory      = new JLabel(Strings.message("ptb.category"));
    private final JLabel lbBlog                 = new JLabel(Strings.message("ptb.prefs.details.blog"));
    private final JLabel lbPostAs               = new JLabel(Strings.message("ptb.prefs.details.post.as"));

    private final boolean hasTemplatesFeature;

    private JComboBox cbTemplate;
    private final JLabel lbTemplate             = new JLabel(Strings.message("te.template"));
    private JButton btnTemplateEditor;

    private final ArrayListModel lmdlCategories = new ArrayListModel();
    private final ArrayListModel lmdlBlogs = new ArrayListModel();
    private ArrayListModel lmTemplateNames;

    private BufferedValueModel vmURL;
    private BufferedValueModel vmUser;
    private BufferedValueModel vmPass;
    private BufferedValueModel vmAPI;

    /**
     * Creates a panel with layout.
     *
     * @param parent parent dialog.
     */
    public BlogDetailsPreferencesPanel(JDialog parent)
    {
        this.parent = parent;
        hasTemplatesFeature = Templates.hasCustomTemplatesFeature();

        initComponents(parent);
        btnTemplateEditor.setEnabled(hasTemplatesFeature);

        // Synthetic panels
        BBFormBuilder builder = new BBFormBuilder("p, 2dlu, p");
        builder.append(rbPublic, rbDraft);
        JPanel pnlPostAs = builder.getPanel();

        // Layout components
        builder = new BBFormBuilder("max(p;60dlu), 4dlu, 125dlu, 2dlu, p, 2dlu, 0:grow", this);

        builder.append(lbTitle, tfTitle);
        builder.nextLine();
        builder.append(lbURL, tfURLSummary);
        builder.append(btnSetup);
        builder.appendUnrelatedComponentsGapRow(2);
        builder.append(lbBlog, cbBlog);
        builder.append(btnFetchBlogs);
        builder.nextLine();
        builder.append(lbDefaultCategory, cbDefaultCategory);
        builder.append(btnFetchCategories);
        builder.nextLine();
        builder.append(lbPostAs, pnlPostAs);
        builder.nextLine();
        builder.append(lbTemplate, cbTemplate);
        builder.append(btnTemplateEditor, UifUtilities.makePublisherPlanIcon(!hasTemplatesFeature));
    }

    /**
     * Binds components to the properties of the preferences proxy.
     *
     * @param parent parent dialog.
     */
    private void initComponents(JDialog parent)
    {
        vmURL = new BufferedValueModel(new PropertyAdapter(proxy, TargetBlog.PROP_API_URL, true), trigger);
        vmUser = new BufferedValueModel(new PropertyAdapter(proxy, TargetBlog.PROP_USER, true), trigger);
        vmPass = new BufferedValueModel(new PropertyAdapter(proxy, TargetBlog.PROP_PASSWORD, true), trigger);

        tfTitle.setDocument(new DocumentAdapter(new PropertyAdapter(proxy, TargetBlog.PROP_TITLE, true)));
        tfURL.setDocument(new DocumentAdapter(vmURL));
        tfURLSummary.setDocument(new DocumentAdapter(new URLSummaryConverter(
            new PropertyAdapter(proxy, TargetBlog.PROP_API_URL, true))));
        tfURLSummary.setEditable(false);
        tfUser.setDocument(new DocumentAdapter(vmUser));
        tfPassword.setDocument(new DocumentAdapter(vmPass));

        taDescription = ComponentsFactory.createInstructionsArea("");

        loadCategoriesLookup();

        ValueModel mdlDefaultCategory = new PropertyAdapter(proxy, TargetBlog.PROP_DEFAULT_CATEGORY, true);
        ComboBoxAdapter adapter = new ComboBoxAdapter((ListModel)lmdlCategories, mdlDefaultCategory);
        cbDefaultCategory = new JComboBox(adapter);

        ValueModel mdlBlog = new PropertyAdapter(proxy, TargetBlog.PROP_BLOG, true);
        adapter = new ComboBoxAdapter((ListModel)lmdlBlogs, mdlBlog);
        cbBlog = new JComboBox(adapter);

        ValueModel mdlDraft = new PropertyAdapter(proxy, TargetBlog.PROP_DRAFT, true);
        rbPublic.setModel(new RadioButtonAdapter(mdlDraft, Boolean.FALSE));
        rbDraft.setModel(new RadioButtonAdapter(mdlDraft, Boolean.TRUE));

        Collection apis = WeblogAPIs.getWeblogAPIs();
        ValueModel mdlAPIs = new PropertyAdapter(proxy, TargetBlog.PROP_API_TYPE, true);
        vmAPI = new BufferedValueModel(mdlAPIs, trigger);
        adapter = new ComboBoxAdapter(apis.toArray(), vmAPI);
        cbWeblogAPIType = new JComboBox(adapter);
        vmAPI.addPropertyChangeListener(new WeblogTypeChangeListener());

        btnSetup = new JButton(new SetupAction(parent));
        btnFetchCategories = new JButton();
        actFetchCategories = new FetchCategoriesAction(); // It uses btnFetchCategories (hence the order)
        btnFetchCategories.setAction(actFetchCategories);
        btnFetchBlogs = new JButton();
        actFetchBlogs = new FetchBlogsAction(); // It uses btnFetchBlogs (hence the order)
        btnFetchBlogs.setAction(actFetchBlogs);

        // Templates
        Set<String> templateNames = Templates.getUserTemplates().keySet();
        lmTemplateNames = new ArrayListModel(templateNames);

        ValueModel mdlTemplates = new PropertyAdapter(proxy, TargetBlog.PROP_TEMPLATE_NAME, true);
        cbTemplate = new JComboBox(new ComboBoxAdapter((ListModel)lmTemplateNames, mdlTemplates));
        btnTemplateEditor = new JButton(new TemplateEditorAction());

        proxy.addPropertyChangeListener(TargetBlogProxy.PROP_BLOG_PREFERENCES, this);
        updateViewState();
    }

    private void loadCategoriesLookup()
    {
        loadLookup(lmdlCategories, proxy.getCategories());
    }

    private void loadBlogsLookup()
    {
        loadLookup(lmdlBlogs, proxy.getBlogs());
    }

    private static void loadLookup(ArrayListModel lm, Object[] items)
    {
        Arrays.sort(items);
        lm.clear();
        lm.addAll(Arrays.asList(items));
    }

    /**
     * Returns the blog preferences object.
     *
     * @return preferences.
     */
    public TargetBlog getBlogPreferences()
    {
        return proxy.getBlogPreferences();
    }

    /**
     * Sets the preferences object to edit. If object is <code>NULL</code>,
     * the view is disabled.
     *
     * @param prefs preferences object.
     */
    public void setBlogPreferences(TargetBlog prefs)
    {
        proxy.setBlogPreferences(prefs);
        loadBlogsLookup();
        loadCategoriesLookup();
    }

    /**
     * Invoked when the proxy preferences object gets loaded / unloaded.
     *
     * @param evt event.
     */
    public void propertyChange(PropertyChangeEvent evt)
    {
        updateViewState();
    }

    /**
     * Updates the state of view components.
     */
    private void updateViewState()
    {
        boolean en = proxy.isLoaded();

        lbTitle.setEnabled(en);
        tfTitle.setEnabled(en);
        lbURL.setEnabled(en);
        tfURLSummary.setEnabled(en);
        btnSetup.setEnabled(en);
        lbDefaultCategory.setEnabled(en);
        cbDefaultCategory.setEnabled(en);
        btnFetchCategories.setEnabled(en);
        lbBlog.setEnabled(en);
        cbBlog.setEnabled(en);
        btnFetchBlogs.setEnabled(en);
        lbPostAs.setEnabled(en);
        rbPublic.setEnabled(en);
        rbDraft.setEnabled(en);
        lbTemplate.setEnabled(en);
        cbTemplate.setEnabled(en);
    }

    /**
     * Opens setup dialog.
     */
    private class SetupAction extends AbstractAction
    {
        private final JDialog parentDialog;
        private BlogSetupDialog dialog;

        /**
         * Creates action.
         *
         * @param parent parent dialog.
         */
        public SetupAction(JDialog parent)
        {
            super(Strings.message("ptb.prefs.details.setup"));
            parentDialog = parent;
        }

        /**
         * Invoked when an action occurs.
         *
         * @param e event.
         */
        public void actionPerformed(ActionEvent e)
        {
            if (dialog == null) dialog = new BlogSetupDialog(parentDialog);
            String oldURL = tfURL.getText();
            dialog.open();
            String newURL = tfURL.getText();

            if (!oldURL.equalsIgnoreCase(newURL))
            {
                proxy.setCategories(null);
                proxy.setDefaultCategory(null);
                proxy.setBlogs(null);
                proxy.setBlog(null);
                actFetchBlogs.actionPerformed(null);
                actFetchCategories.actionPerformed(null);
            }
        }
    }

    /**
     * The dialog for setup and probing blogs.
     */
    private class BlogSetupDialog extends AbstractDialog
    {
        private final JLabel lbStatus;
        private JButton btnOK;
        private JButton btnCancel;
        private ProgressSpinner spnProgress;

        /**
         * Creates setup dialog.
         *
         * @param parent parent dialog.
         */
        public BlogSetupDialog(JDialog parent)
        {
            super(parent, Strings.message("ptb.prefs.details.setup.title"), true);
            lbStatus = new JLabel(Strings.message("ptb.prefs.details.setup.status.idle"));

            spnProgress = new ProgressSpinner();
            spnProgress.setText(Strings.message("ptb.prefs.details.setup.status.connecting"));
        }

        /**
         * Creates main page component.
         *
         * @return component.
         */
        protected JComponent buildContent()
        {
            JPanel content = new JPanel(new BorderLayout());
            content.add(buildMainPane(), BorderLayout.CENTER);
            content.add(buildButtonsBar(), BorderLayout.SOUTH);
            return content;
        }

        /**
         * Creates main pane.
         *
         * @return main pane.
         */
        private Component buildMainPane()
        {
            BBFormBuilder builder = new BBFormBuilder("p, 2dlu, max(p;50dlu), 75dlu");
            builder.setDefaultDialogBorder();

            builder.append(Strings.message("ptb.prefs.details.setup.type"), cbWeblogAPIType);
            builder.append(Strings.message("ptb.prefs.details.setup.url"), tfURL, 2);
            builder.nextLine();
            builder.append(Strings.message("ptb.prefs.details.setup.user"), tfUser, 2);
            builder.nextLine();
            builder.append(Strings.message("ptb.prefs.details.setup.pass"), tfPassword, 2);
            builder.nextLine();
            builder.appendUnrelatedComponentsGapRow();
            builder.nextLine();
            builder.appendRow("75dlu");
            builder.append(new JScrollPane(taDescription), 4, CellConstraints.FILL, CellConstraints.FILL);
            builder.nextLine();
            builder.appendUnrelatedComponentsGapRow();
            builder.nextLine();
            builder.append(Strings.message("ptb.prefs.details.setup.status"), lbStatus, 2);
            builder.appendRow("0:grow");

            return builder.getPanel();
        }

        /**
         * Creates buttons bar.
         *
         * @return bar.
         */
        private Component buildButtonsBar()
        {
            btnOK = createOKButton(true);
            btnOK.setAction(new TestBlogSetupAction());
            btnCancel = createCancelButton();

            ButtonBarBuilder builder = new ButtonBarBuilder();

            builder.getPanel().setBorder(Constants.DIALOG_BUTTON_BAR_BORDER);
            builder.addFixed(spnProgress);
            builder.addUnrelatedGap();
            builder.addGlue();
            builder.addGriddedButtons(new JButton[] { btnOK, btnCancel });

            return builder.getPanel();
        }

        /**
         * Opens the dialog.
         */
        public void open()
        {
            status(Strings.message("ptb.prefs.details.setup.status.idle"), false);
            super.open();
        }

        /**
         * Commit changes when accepting the dialog.
         */
        public void doAccept()
        {
            trigger.triggerCommit();
            super.doAccept();
        }

        /**
         * Flush all the fields in the setup dialog when cancelled.
         */
        public void doCancel()
        {
            trigger.triggerFlush();
            super.doCancel();
        }

        /**
         * Sets status and font.
         *
         * @param text status text.
         * @param bold <code>TRUE</code> for bold font.
         */
        private void status(String text, boolean bold)
        {
            lbStatus.setText(text);
            lbStatus.setFont(lbStatus.getFont().deriveFont(bold ? Font.BOLD :Font.PLAIN));
        }

        /**
         * Tests connection settings.
         */
        private class TestBlogSetupAction extends AbstractAction
        {
            /**
             * Creates action.
             */
            public TestBlogSetupAction()
            {
                super(Strings.message("ptb.prefs.details.setup.test"));
            }

            /**
             * Invoked when an action occurs.
             *
             * @param e event.
             */
            public void actionPerformed(ActionEvent e)
            {
                spnProgress.start();
                enableButtons(false);

                new Thread("Testing Connection")
                {
                    { setDaemon(true); }

                    /**
                     * Invoked when running a thread.
                     */
                    public void run()
                    {
                        TargetBlog tb = new TargetBlog();
                        tb.setApiType((IWeblogAPI)vmAPI.getValue());
                        tb.setApiURL((String)vmURL.getValue());
                        tb.setUser((String)vmUser.getValue());
                        tb.setPassword((String)vmPass.getValue());
                        final String msg = tb.testConnection();

                        if (msg == null) vmURL.setValue(tb.getApiURL());

                        SwingUtilities.invokeLater(new Runnable()
                        {
                            public void run()
                            {
                                spnProgress.stop();
                                onTestComplete(msg);
                            }
                        });
                    }
                }.start();
            }

            /**
             * Invoked when the connection testing is complete.
             *
             * @param msg <code>NULL</code> if fine, or error message
             */
            private void onTestComplete(String msg)
            {
                enableButtons(true);
                if (msg == null)
                {
                    status(Strings.message("ptb.prefs.details.setup.status.detected"), true);
                    doAccept();
                } else
                {
                    status(msg, false);
                }
            }

            /**
             * Enables and disables buttons.
             *
             * @param en <code>TRUE</code> to enable.
             */
            private void enableButtons(boolean en)
            {
                btnOK.setEnabled(en);
                btnCancel.setEnabled(en);
            }
        }
    }

    /**
     * Fetches the list of categories.
     */
    private class FetchCategoriesAction extends AbstractFetchLookupAction
    {
        /**
         * Creates action.
         */
        public FetchCategoriesAction()
        {
            super(cbDefaultCategory, btnFetchCategories, Strings.message("ptb.prefs.details.category.update"));
        }

        /**
         * This method is called asynchronously when the action takes place. You need
         * to call loading procedure from it and the callback should be executed from
         * within EDT upon completion.
         *
         * @param edtCallback callback to execute.
         */
        protected void startAsyncLoading(Runnable edtCallback)
        {
            proxy.loadCategories(edtCallback);
        }

        /** This method is called when the lookup combo-box can be reloaded with new data. */
        protected void loadLookup()
        {
            loadCategoriesLookup();
        }

        /**
         * After the async loading the state is checked to learn whether the lookup
         * update is neccessary.
         *
         * @return <code>TRUE</code> if loading was successful and lookup should be updated.
         */
        protected boolean isSuccessfulLoading()
        {
            return proxy.getCategories().length > 0;
        }
    }

    /**
     * Fetches the list of blogs.
     */
    private class FetchBlogsAction extends AbstractFetchLookupAction
    {
        /**
         * Creates action.
         */
        public FetchBlogsAction()
        {
            super(cbBlog, btnFetchBlogs, Strings.message("ptb.prefs.details.blog.update"));
        }

        /**
         * This method is called asynchronously when the action takes place. You need
         * to call loading procedure from it and the callback should be executed from
         * within EDT upon completion.
         *
         * @param edtCallback callback to execute.
         */
        protected void startAsyncLoading(Runnable edtCallback)
        {
            proxy.loadBlogs(edtCallback);
        }

        /** This method is called when the lookup combo-box can be reloaded with new data. */
        protected void loadLookup()
        {
            loadBlogsLookup();
        }

        /**
         * After the async loading the state is checked to learn whether the lookup
         * update is neccessary.
         *
         * @return <code>TRUE</code> if loading was successful and lookup should be updated.
         */
        protected boolean isSuccessfulLoading()
        {
            return proxy.getBlogs().length > 0;
        }
    }

    /** This converter returns <i>Not Set</i> when URL isn't set. */
    private static class URLSummaryConverter extends AbstractConverter
    {
        /**
         * Creates converter.
         *
         * @param valueModel model to convert.
         */
        public URLSummaryConverter(ValueModel valueModel)
        {
            super(valueModel);
        }

        /**
         * Converts the data from the subject.
         *
         * @param object object.
         *
         * @return value.
         */
        public Object convertFromSubject(Object object)
        {
            String url = (String)object;
            return StringUtils.isEmpty(url) ? Strings.message("ptb.prefs.details.not.set") : url;
        }

        /**
         * We don't set anything.
         *
         * @param object value.
         */
        public void setValue(Object object)
        {
        }
    }

    /**
     * Invoked when a template editor is called.
     */
    private class TemplateEditorAction extends AbstractAction
    {
        private TemplateEditorAction()
        {
            super(Strings.message("te.edit"));
        }

        public void actionPerformed(ActionEvent e)
        {
            String templateName = (String)cbTemplate.getSelectedItem();

            Editor editor = new Editor(parent);
            editor.open(Templates.getByName(templateName));

            // Repopulate the templates list
            Collection<String> templateNames = Templates.getUserTemplateNames();
            lmTemplateNames.clear();
            lmTemplateNames.addAll(templateNames);

            if (templateName != null)
            {
                if (templateNames.contains(templateName))
                {
                    cbTemplate.setSelectedItem(templateName);
                } else
                {
                    cbTemplate.setSelectedIndex(0);
                }
            }
        }
    }

    private class WeblogTypeChangeListener implements PropertyChangeListener
    {
        private String lastEnteredURL;

        /**
         * This method gets called when a bound property is changed.
         *
         * @param evt A PropertyChangeEvent object describing the event source and the property that has changed.
         */

        public void propertyChange(PropertyChangeEvent evt)
        {
            IWeblogAPI type = (IWeblogAPI)vmAPI.getValue();
            if (type != null)
            {
                boolean newEnabled = type.isApiUrlApplicable();
                boolean oldEnabled = tfURL.isEnabled();

                if (newEnabled != oldEnabled)
                {
                    tfURL.setEnabled(newEnabled);
                    if (newEnabled)
                    {
                        tfURL.setText(lastEnteredURL);
                    } else
                    {
                        lastEnteredURL = tfURL.getText();
                        tfURL.setText(Strings.message("ptb.prefs.details.setup.not.applicable"));
                    }
                }

                taDescription.setText(type.getDescription());
            }
        }
    }
}
TOP

Related Classes of com.salas.bb.remixfeeds.prefs.BlogDetailsPreferencesPanel$WeblogTypeChangeListener

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.