Package com.salas.bb.dialogs

Source Code of com.salas.bb.dialogs.AdvancedPreferencesPanel$BIDModeToStringConverter

// 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: AdvancedPreferencesPanel.java,v 1.76 2007/10/11 09:34:34 spyromus Exp $
//

package com.salas.bb.dialogs;

import com.jgoodies.binding.adapter.*;
import com.jgoodies.binding.beans.PropertyAdapter;
import com.jgoodies.binding.value.AbstractConverter;
import com.jgoodies.binding.value.BufferedValueModel;
import com.jgoodies.binding.value.ValueModel;
import com.jgoodies.uif.util.SystemUtils;
import com.jgoodies.uifextras.convenience.TipOfTheDayDialog;
import com.salas.bb.core.ApplicationLauncher;
import com.salas.bb.core.GlobalController;
import com.salas.bb.domain.prefs.StarzPreferences;
import com.salas.bb.domain.prefs.UserPreferences;
import com.salas.bb.utils.BrowserLauncher;
import com.salas.bb.utils.OSSettings;
import com.salas.bb.utils.SpinnerModelAdapter;
import com.salas.bb.utils.StringUtils;
import com.salas.bb.utils.i18n.Strings;
import com.salas.bb.utils.notification.NotificationArea;
import com.salas.bb.utils.uif.BBFormBuilder;
import com.salas.bb.utils.uif.ComponentsFactory;
import com.salas.bb.utils.uif.StateUpdatingToggleListener;
import com.salas.bb.utils.uif.VertialScrollablePanel;
import com.salas.bb.views.settings.FeedRenderingSettings;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.regex.Pattern;

/**
* Builds the Advanced Options Panel for the General Preferences Dialog.
*/
public class AdvancedPreferencesPanel extends JPanel
{
    private static final String PAT_IP = "([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])";
    private static final String PAT_SN = "[a-z][a-z0-9]+";
    private static final String PAC_REC = "\\s*("+ PAT_IP +"(\\."+ PAT_IP +"){3}|"+ PAT_SN +"(\\."+ PAT_SN +")*)\\s*";
    private static final Pattern PAT_VALID_PROXY_EX =
        Pattern.compile("^"+ PAC_REC +"(,"+ PAC_REC +")*$",
        Pattern.CASE_INSENSITIVE);

    private UserPreferences             userPrefs;
    private StarzPreferences            starzPrefs;
    private final FeedRenderingSettings feedRS;
    private ValueModel                  triggerChannel;

    private JCheckBox                   chShowTipsBox;
    private JCheckBox                   chDoUpdatesCheck;

    private JTextField                  tfInternetBrowser;
    private JCheckBox                   chProxyEnabled;
    private JTextField                  tfProxyHost;
    private JLabel                      lbProxyPort;
    private JSpinner                    spinProxyPort;
    private JLabel                      lbProxyExclusions;
    private JTextField                  tfProxyExclusions;

    private int                         initActivityLimit;
    private int                         initHightlightsLimit;

    private JCheckBox                   chAAText;
   
    private JCheckBox                   chShowUnreadButtonMenu;

    private JSpinner                    spinFeedImportLimit;

    private JTextField                  tfPingURL;
    private JCheckBox                   chPing;

    private JRadioButton                rbGSMFirst;
    private JRadioButton                rbGSMLastSeen;
    private JRadioButton                rbGSMNoFeed;

    private JCheckBox                   chHideOldArticles;
    private JCheckBox                   chDisplayFullTitles;
    private JCheckBox                   chSortingAscending;
    private JTextField                  tfSuppressOlderThan;
    private JCheckBox                   chCopyLinksInHREFFormat;
    private JCheckBox                   chBrowseOnTitleDblClick;

    private JCheckBox                   chShowAppIconInSystray;
    private JCheckBox                   chMinimizeToSystray;
    private JComboBox                   cbBIDMode;
    private JCheckBox chAlwaysUseEnglish;

    /**
     * Constructs the <i>Advanced</i> panel for the preferences dialog.
     *
     * @param aUserPrefs        user preferences.
     * @param aStarzPrefs       starz preferences.
     * @param aFeedRS           feed rendering settings.
     * @param aTriggerChannel   triggers a commit when apply is pressed.
     */
    public AdvancedPreferencesPanel(UserPreferences aUserPrefs, StarzPreferences aStarzPrefs,
                                    FeedRenderingSettings aFeedRS,
                                    ValueModel aTriggerChannel)
    {
        feedRS = aFeedRS;

        this.userPrefs = aUserPrefs;
        this.starzPrefs = aStarzPrefs;
        this.triggerChannel = aTriggerChannel;

        initComponents(triggerChannel);
        build();
    }

    // Component Creation and Initialization ********************************

    private void initComponents(ValueModel triggerChannel)
    {
        chShowTipsBox = ComponentsFactory.createCheckBox(
            Strings.message("userprefs.tab.general.show.tip.of.the.day"),
            new ToggleButtonAdapter(new BufferedValueModel(TipOfTheDayDialog.showingTipsModel(),
                triggerChannel)));

        String msg = Strings.message("userprefs.tab.general.check.for.new.versions");
        if (ApplicationLauncher.isAutoUpdatesEnabled())
        {
            chDoUpdatesCheck = ComponentsFactory.createCheckBox(
                msg, new ToggleButtonAdapter(new BufferedValueModel(new PropertyAdapter(userPrefs,
                    UserPreferences.PROP_CHECKING_FOR_UPDATES_ON_STARTUP),
                    triggerChannel)));
        } else
        {
            msg = msg.replaceAll("&", "");
            chDoUpdatesCheck = new JCheckBox(msg);
            chDoUpdatesCheck.setSelected(true);
            chDoUpdatesCheck.setEnabled(false);
        }

        chAlwaysUseEnglish = ComponentsFactory.createCheckBox(
            Strings.message("userprefs.tab.advanced.always.use.english"),
            new ToggleButtonAdapter(new BufferedValueModel(new PropertyAdapter(userPrefs,
                UserPreferences.PROP_ALWAYS_USE_ENGLISH),
                triggerChannel)));
       
        tfInternetBrowser = new JTextField();
        tfInternetBrowser.setDocument(new DocumentAdapter(new BufferedValueModel(
            new PropertyAdapter(userPrefs, UserPreferences.PROP_INTERNET_BROWSER),
            triggerChannel)));

        if (BrowserLauncher.isUsingJWSBrowser())
        {
            tfInternetBrowser.setEnabled(false);
            tfInternetBrowser.setToolTipText(Strings.message("userprefs.tab.advanced.browser.tooltip.disabled"));
        } else
        {
            tfInternetBrowser.setEnabled(true);
            tfInternetBrowser.setToolTipText(Strings.message("userprefs.tab.advanced.browser.tooltip.enabled"));
        }

        initProxyComponents(triggerChannel);

        SpinnerModelAdapter spinModelFeedSelectionDelay = new SpinnerModelAdapter(
            new BoundedRangeAdapter(new BufferedValueModel(new PropertyAdapter(userPrefs,
                UserPreferences.PROP_FEED_SELECTION_DELAY), triggerChannel), 0, 0, 1000));
        spinModelFeedSelectionDelay.setStepSize(100);

        chAAText = createCheckBox(userPrefs, Strings.message("userprefs.tab.advanced.antialiased.fonts"),
            UserPreferences.PROP_AA_TEXT);

        // The following code registers listener on Apply/Accept actions to track down
        // changes in BlogStarz limits. If changes are detected then channel list is
        // repainted.

        saveInitialLimits();
        triggerChannel.addValueChangeListener(new PropertyChangeListener()
        {
            public void propertyChange(PropertyChangeEvent evt)
            {
                if (Boolean.TRUE.equals(evt.getNewValue())) doRepaintChannelList();
            }
        });

        chShowUnreadButtonMenu = createCheckBox(userPrefs,
            Strings.message("userprefs.tab.advanced.show.the.unread.buttons.menu"),
            UserPreferences.PROP_SHOW_UNREAD_BUTTON_MENU);

        SpinnerModelAdapter spinModelFeedImportLimit =
            new SpinnerModelAdapter(new BoundedRangeAdapter(
                new BufferedValueModel(new PropertyAdapter(userPrefs,
                    UserPreferences.PROP_FEED_IMPORT_LIMIT),
                    triggerChannel), 1, 1, UserPreferences.MAX_FEED_IMPORT_LIMITATION));
        spinModelFeedImportLimit.setStepSize(100);
        spinFeedImportLimit = new JSpinner(spinModelFeedImportLimit);

        initGuideComponents(triggerChannel);

        chHideOldArticles = createCheckBox(feedRS,
            Strings.message("userprefs.tab.articles.hide.articles.older.than"), "suppressingOlderThan");
        chDisplayFullTitles = createCheckBox(feedRS,
            Strings.message("userprefs.tab.articles.display.full.titles"), "displayingFullTitles");
        chSortingAscending = createCheckBox(feedRS,
            Strings.message("userprefs.tab.articles.sort.earlier.articles.first"), "sortingAscending");

        tfSuppressOlderThan = new JTextField();
        tfSuppressOlderThan.setDocument(new DocumentAdapter(new BufferedValueModel(
            new PropertyAdapter(feedRS, "suppressOlderThanString"), triggerChannel)));

        chCopyLinksInHREFFormat = createCheckBox(userPrefs,
            Strings.message("userprefs.tab.articles.use.href.format.for.links.copied.to.clipboard"),
            UserPreferences.PROP_COPY_LINKS_IN_HREF_FORMAT);
        chBrowseOnTitleDblClick = createCheckBox(userPrefs,
            Strings.message("userprefs.tab.articles.browse.on.double.click.over.the.title"),
            UserPreferences.PROP_BROWSE_ON_DBL_CLICK);

        chShowAppIconInSystray = createCheckBox(userPrefs,
            Strings.message("userprefs.tab.advanced.show.appicon.in.systray"),
            UserPreferences.PROP_SHOW_APPICON_IN_SYSTRAY);
        chMinimizeToSystray = createCheckBox(userPrefs,
            Strings.message("userprefs.tab.advanced.minimize.to.systray"),
            UserPreferences.PROP_MINIMIZE_TO_SYSTRAY);

        // Dock icon
        ValueModel modeModel = new BufferedValueModel(
            new BIDModeToStringConverter(new PropertyAdapter(userPrefs, UserPreferences.PROP_DIB_MODE)),
            triggerChannel);

        cbBIDMode = new JComboBox(new ComboBoxAdapter(BIDModeToStringConverter.MODES, modeModel));
    }

    private void initGuideComponents(ValueModel triggerChannel)
    {
        // Guide selection mode group
        ValueModel gsmModel = new BufferedValueModel(
            new PropertyAdapter(userPrefs, UserPreferences.PROP_GUIDE_SELECTION_MODE),
            triggerChannel);

        rbGSMFirst = createRadioButton(gsmModel,
            UserPreferences.GSM_FIRST_FEED,
            Strings.message("userprefs.tab.guides.select.first.feed"));
        rbGSMLastSeen = createRadioButton(gsmModel,
            UserPreferences.GSM_LAST_SEEN_FEED,
            Strings.message("userprefs.tab.guides.select.last.seen.feed"));
        rbGSMNoFeed = createRadioButton(gsmModel,
            UserPreferences.GSM_NO_FEED,
            Strings.message("userprefs.tab.guides.select.no.feed"));

        // Publication
        chPing = createCheckBox(userPrefs,
            Strings.message("userprefs.tab.guides.ping.url"),
            UserPreferences.PROP_PING_ON_RL_PUBLICATION);
        chPing.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                updatePingURLState();
            }
        });
        tfPingURL = new JTextField();
        tfPingURL.setDocument(new DocumentAdapter(new BufferedValueModel(
            new PropertyAdapter(userPrefs, UserPreferences.PROP_PING_ON_RL_PUBLICATION_URL),
            triggerChannel)));
        updatePingURLState();

        String ttPing = Strings.message("userprefs.tab.guides.ping.wording");
        chPing.setToolTipText(ttPing);
        tfPingURL.setToolTipText(ttPing);
    }

    /** Updates the state of the field depending on the check-state of the box. */
    private void updatePingURLState()
    {
        tfPingURL.setEnabled(chPing.isSelected());
    }

    /**
     * Creates mode radio-button.
     *
     * @param model     GSM model.
     * @param mode      mode value.
     * @param caption   caption.
     *
     * @return button.
     */
    private JRadioButton createRadioButton(ValueModel model, int mode, String caption)
    {
        return ComponentsFactory.createRadioButton(caption, new RadioButtonAdapter(model, mode));
    }

    /**
     * Initializes proxy components.
     *
     * @param triggerChannel trigger.
     */
    private void initProxyComponents(ValueModel triggerChannel)
    {
        chProxyEnabled = createCheckBox(userPrefs, Strings.message("userprefs.tab.advanced.use.proxy"),
            UserPreferences.PROP_PROXY_ENABLED);

        tfProxyHost = new JTextField();
        tfProxyHost.setDocument(new DocumentAdapter(new BufferedValueModel(
            new PropertyAdapter(userPrefs, UserPreferences.PROP_PROXY_HOST), triggerChannel)));

        lbProxyPort = ComponentsFactory.createLabel(Strings.message("userprefs.tab.advanced.use.proxy.port"));
        spinProxyPort = new JSpinner(new SpinnerModelAdapter(new BoundedRangeAdapter(
            new BufferedValueModel(new PropertyAdapter(userPrefs, UserPreferences.PROP_PROXY_PORT),
            triggerChannel), 80, 80, 65536)));
        spinProxyPort.setEditor(new JSpinner.NumberEditor(spinProxyPort, "#"));

        lbProxyExclusions = ComponentsFactory.createLabel(Strings.message("userprefs.tab.advanced.no.proxy.for"));
        tfProxyExclusions = new JTextField();
        tfProxyExclusions.setDocument(new DocumentAdapter(new BufferedValueModel(
            new PropertyAdapter(userPrefs, UserPreferences.PROP_PROXY_EXCLUSIONS), triggerChannel)));

        StateUpdatingToggleListener.install(chProxyEnabled, tfProxyHost, lbProxyPort, spinProxyPort,
            lbProxyExclusions, tfProxyExclusions);
    }

    /**
     * Helper function to create a checkbox.
     * @param obj Object holding property.
     * @param label Label for checkbox.
     * @param propertyName Property to save on object.
     * @return new JCheckbox.
     */
    private JCheckBox createCheckBox(Object obj, String label, String propertyName)
    {
        return ComponentsFactory.createCheckBox(label, new ToggleButtonAdapter(
            new BufferedValueModel(new PropertyAdapter(obj, propertyName), triggerChannel)));
    }

    /**
     * Saves the limits of parameters for future comparison.
     */
    private void saveInitialLimits()
    {
        initActivityLimit = starzPrefs.getTopActivity();
        initHightlightsLimit = starzPrefs.getTopHighlights();
    }

    /**
     * Performs repainting of channels list if starz limits changed changed.
     */
    private void doRepaintChannelList()
    {
        if (starzPrefs.getTopActivity() != initActivityLimit ||
            starzPrefs.getTopHighlights() != initHightlightsLimit)
        {
            saveInitialLimits();
            GlobalController.SINGLETON.getMainFrame().getFeedsPanel().repaint();
        }
    }

    /**
     * Creates a FormLayout and adds the UI components using a PanelBuilder.
     */
    private void build()
    {
        JPanel panel = new VertialScrollablePanel();

        String version = System.getProperty("java.vm.version");
        boolean is15 = version != null && version.startsWith("1.5");

        BBFormBuilder builder = new BBFormBuilder("7dlu, p, 2dlu, 40dlu, 70dlu:grow", panel);
        builder.setDefaultDialogBorder();

        builder.appendSeparator(Strings.message("userprefs.tab.advanced.separator.on.startup"));
        builder.setLeadingColumnOffset(1);
        builder.append(chShowTipsBox, 4);
        builder.append(chDoUpdatesCheck, 4);
        builder.append(chAlwaysUseEnglish, 4);

        builder.setLeadingColumnOffset(1);
        builder.appendSeparator(Strings.message("userprefs.tab.advanced.separator.network"));
        builder.nextColumn();
        builder.append(Strings.message("userprefs.tab.advanced.browser"), tfInternetBrowser, 2);
        builder.append(chProxyEnabled);
        builder.append(buildProxyPanel(), 2);
        builder.append(lbProxyExclusions);
        builder.append(tfProxyExclusions, 2);
        tfProxyExclusions.setToolTipText(Strings.message("userprefs.tab.advanced.no.proxy.for.notes"));

        builder.appendSeparator(Strings.message("userprefs.tab.advanced.separator.interface"));
        builder.nextLine();
        builder.append(Strings.message("userprefs.tab.advanced.feed.import.limit"), spinFeedImportLimit);
        builder.nextLine();
        builder.append(chShowUnreadButtonMenu, 4);
        if (is15) builder.append(chAAText, 4);

        if (NotificationArea.isSupported())
        {
            if (!SystemUtils.IS_OS_MAC) builder.append(chShowAppIconInSystray, 4);
            if (OSSettings.isMinimizeToSystraySupported()) builder.append(chMinimizeToSystray, 4);
        }

        // Mac-specific Dock icon settings
        if (SystemUtils.IS_OS_MAC) builder.append(Strings.message("userprefs.tab.advanced.dock.icon"), cbBIDMode, 2);

        builder.appendSeparator(Strings.message("userprefs.tab.guides.on.selection"));
        builder.append(rbGSMFirst, 4);
        builder.append(rbGSMLastSeen, 4);
        builder.append(rbGSMNoFeed, 4);

        builder.appendSeparator(Strings.message("userprefs.tab.guides.on.publication"));
        builder.append(chPing);
        builder.append(tfPingURL, 2);

        builder.appendSeparator(Strings.message("userprefs.tab.advanced.articles"));
        builder.append(chSortingAscending, 4);
        builder.append(chHideOldArticles, tfSuppressOlderThan);
        builder.nextLine();
        builder.append(chDisplayFullTitles, 4);
        builder.append(chCopyLinksInHREFFormat, 4);
        builder.append(chBrowseOnTitleDblClick, 4);

        // Finish
        setLayout(new BorderLayout());
        JScrollPane sp = new JScrollPane(panel);
        sp.setBorder(BorderFactory.createEmptyBorder());
        sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        add(sp, BorderLayout.CENTER);
    }

    /**
     * Creates proxy panel.
     *
     * @return panel.
     */
    private JPanel buildProxyPanel()
    {
        BBFormBuilder builder = new BBFormBuilder("50dlu:grow, 10dlu, pref, 2dlu, 30dlu");
        builder.append(tfProxyHost);
        builder.append(lbProxyPort, spinProxyPort);
        lbProxyPort.setLabelFor(spinProxyPort);

        return builder.getPanel();
    }

    public String checkValidity()
    {
        String msg = null;
        String txt = tfProxyExclusions.getText();

        if (!isValidProxyExclusions(txt))
        {
            msg = "Please correct the list of Proxy Exclusions.\n" +
                "It should be the comma-separated list of IP\n" +
                "addresses or site names.";
        }

        return msg;
    }

    /**
     * Checks if the text is a valid list of proxy exclusions.
     *
     * @param txt text.
     *
     * @return <code>TRUE</code> if valid.
     */
    static boolean isValidProxyExclusions(String txt)
    {
        return StringUtils.isEmpty(txt) || PAT_VALID_PROXY_EX.matcher(txt).matches();

    }

    /**
     * Converter of BID mode to string and vice-versa.
     */
    private static class BIDModeToStringConverter extends AbstractConverter
    {
        public static final String[] MODES = {
            Strings.message("userprefs.tab.advanced.dock.icon.invisible"),
            Strings.message("userprefs.tab.advanced.dock.icon.unread.articles"),
            Strings.message("userprefs.tab.advanced.dock.icon.unread.feeds")
        };

        /**
         * Creates converter for some mode.
         *
         * @param model model.
         */
        public BIDModeToStringConverter(ValueModel model)
        {
            super(model);
        }

        /**
         * Converts from the subject model.
         *
         * @param object object.
         *
         * @return converted version.
         */
        public Object convertFromSubject(Object object)
        {
            int mode = (Integer)object;
            return MODES[mode];
        }

        /**
         * Sets value into the subject mode.
         *
         * @param object value.
         */
        public void setValue(Object object)
        {
            // Arrays.binarySearch doesn't work
            int index = -1;
            for (int i = 0; index < 0 && i < MODES.length; i++)
            {
                String mode = MODES[i];
                if (mode.equals(object)) index = i;
            }

            subject.setValue(index);
        }
    }
}

TOP

Related Classes of com.salas.bb.dialogs.AdvancedPreferencesPanel$BIDModeToStringConverter

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.