org.l2x6.eircc.ui.prefs.IrcPreferences.java Source code

Java tutorial

Introduction

Here is the source code for org.l2x6.eircc.ui.prefs.IrcPreferences.java

Source

/*
 * Copyright (c) 2014 Peter Palaga.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.l2x6.eircc.ui.prefs;

import java.text.MessageFormat;
import java.time.Duration;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.l2x6.eircc.core.model.AbstractIrcChannel;
import org.l2x6.eircc.core.model.IrcMessage;
import org.l2x6.eircc.core.model.IrcNotificationLevel;
import org.l2x6.eircc.core.model.IrcNotificationLevelProvider;
import org.l2x6.eircc.core.model.PlainIrcMessage;
import org.l2x6.eircc.ui.EirccUi;
import org.l2x6.eircc.ui.IrcUiMessages;
import org.l2x6.eircc.ui.editor.IrcDefaultMessageFormatter;
import org.l2x6.eircc.ui.editor.IrcNotificationMessageFormatter;
import org.l2x6.eircc.ui.editor.IrcSearchMessageFormatter;
import org.l2x6.eircc.ui.editor.IrcSystemMessageFormatter;
import org.l2x6.eircc.ui.misc.Colors;
import org.l2x6.eircc.ui.misc.ExtendedTextStyle;

/**
 * @author <a href="mailto:ppalaga@redhat.com">Peter Palaga</a>
 */
public class IrcPreferences implements IrcNotificationLevelProvider {

    /**
     * Preference keys and their default values.
     *
     * @author <a href="mailto:ppalaga@redhat.com">Peter Palaga</a>
     *
     */
    public enum PreferenceKey {

        WATCHED_CHANNELS("watched.channels", ""), WATCHED_NICKS("watched.nicks", ""); //$NON-NLS-1$

        private final Object defaultValue;
        private final String key;

        /**
         * Make sure that the type of {@code defaultValue} is supported by
         * {@link IPreferencesService}.
         *
         * @param value
         * @param defaultValue
         */
        private PreferenceKey(String value, Object defaultValue) {
            this.key = value;
            this.defaultValue = defaultValue;
        }

        public Object getDefaultValue() {
            return defaultValue;
        }

        @Override
        public String toString() {
            return key;
        }

    }

    private static final Duration COMMAND_TIMEOUT = Duration.ofSeconds(3);

    private static final long DEFAULT_EDITOR_LOOK_BACK_BYTE_LIMIT = 8 * 1024;
    private static final String DEFAULT_NOTIFICATION_MESSAGE_COLOR_KEY = IrcPreferences.class.getName()
            + ".defaultNotificationMessageColor";

    private static final Duration DEFAULT_PING_INTERVAL = Duration.ofMinutes(1);

    private static final IrcPreferences INSTANCE = new IrcPreferences();
    private static final IInputValidator PATTERN_VALIDATOR = new IInputValidator() {
        /**
         * Validates the String. Returns null for no error, or an error message
         *
         * @param newText
         *            the String to validate
         * @return String
         */
        public String isValid(String newText) {
            if (newText.isEmpty()) {
                return IrcUiMessages.IrcNotificationsPreferencePage_cannotBeEmpty;
            }

            try {
                Pattern.compile(newText);
            } catch (PatternSyntaxException e) {
                return MessageFormat.format(IrcUiMessages.IrcNotificationsPreferencePage_invalidPattern,
                        e.getMessage());
            }
            return null;
        }
    };

    public static final char WATCHED_OBJECT_DELIMITER = ' ';

    public static IrcPreferences getInstance() {
        return INSTANCE;
    }

    private final IrcDefaultMessageFormatter defaultFormatter = new IrcDefaultMessageFormatter(this);

    private final IrcSystemMessageFormatter errorFormatter = new IrcSystemMessageFormatter(this);
    private final ExtendedTextStyle messageTimeStyle;

    private final IrcNotificationMessageFormatter notificationFormatter = new IrcNotificationMessageFormatter(this);
    private final ExtendedTextStyle notificationMessageStyle;
    private IrcSearchMessageFormatter searchFormatter = new IrcSearchMessageFormatter(this);

    private final IrcSystemMessageFormatter systemFormatter = new IrcSystemMessageFormatter(this);
    private final ExtendedTextStyle systemMessageStyle;
    private final IrcUserStyler[] userStylers;
    private final ExtendedTextStyle[] userStyles;
    private final ExtendedTextStyle[] userStylesNamingMe;

    private Set<String> watchedChannels;

    private Map<String, Pattern> watchedNicks;

    /**
     *
     */
    public IrcPreferences() {
        super();
        ColorRegistry reg = JFaceResources.getColorRegistry();
        systemMessageStyle = new ExtendedTextStyle(
                Display.getDefault().getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND));

        reg.put(DEFAULT_NOTIFICATION_MESSAGE_COLOR_KEY, new RGB(254, 128, 0));
        notificationMessageStyle = new ExtendedTextStyle(reg.get(DEFAULT_NOTIFICATION_MESSAGE_COLOR_KEY));
        messageTimeStyle = new ExtendedTextStyle(
                Display.getDefault().getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND));

        Colors colors = Colors.getInstance();
        String keyPrefix = this.getClass().getName() + ".user#";
        userStyles = new ExtendedTextStyle[colors.getColorCount()];
        userStylesNamingMe = new ExtendedTextStyle[colors.getColorCount()];
        userStylers = new IrcUserStyler[colors.getColorCount()];
        for (int i = 0; i < userStyles.length; i++) {
            String key = keyPrefix + i;
            reg.put(key, colors.getRGB(i));
            Color c = reg.get(key);
            userStyles[i] = new ExtendedTextStyle(c);
            userStylesNamingMe[i] = new ExtendedTextStyle(c, SWT.BOLD);
            userStylers[i] = new IrcUserStyler(this, i);
        }

    }

    public void addWatchedChannel(String channel) {
        getWatchedChannels().add(channel);
        setCollection(PreferenceKey.WATCHED_CHANNELS, watchedChannels);
    }

    public void addWatchedNickPattern(String nick) {
        getWatchedNicks().put(nick, Pattern.compile(nick));
        setCollection(PreferenceKey.WATCHED_NICKS, watchedNicks.keySet());
    }

    public void dispose() {

    }

    /**
     * @return
     */
    public String getAddresseeSuffix() {
        return ": ";
    }

    /**
     * Calls
     * {@link IPreferencesService#getBoolean(String, String, String, org.eclipse.core.runtime.preferences.IScopeContext[])}
     * using {@link Plugin#ID} and a default ({@code null}) context order.
     *
     * @param key
     * @return
     */
    public boolean getBoolean(PreferenceKey key) {
        IPreferenceStore store = EirccUi.getDefault().getPreferenceStore();
        return store.getBoolean(key.toString());
        // return preferencesService.getBoolean(EirccUi.PLUGIN_ID,
        // key.toString(), ((Boolean) key.getDefaultValue()).booleanValue(),
        // null);
    }

    /**
     * @return
     */
    public boolean getEditorAutoInsert() {
        return true;
    }

    /**
     * @return
     */
    public boolean getEditorAutoPrefixCompletion() {
        return true;
    }

    /**
     * @param m
     * @return
     */
    public IrcDefaultMessageFormatter getFormatter(PlainIrcMessage m) {
        switch (m.getType()) {
        case SYSTEM:
            return systemFormatter;
        case ERROR:
            return errorFormatter;
        case NOTIFICATION:
            return notificationFormatter;
        default:
            return defaultFormatter;
        }
    }

    /**
     * @return
     */
    public long getLookbackTresholdBytes() {
        return DEFAULT_EDITOR_LOOK_BACK_BYTE_LIMIT;
    }

    public ExtendedTextStyle getMessageTimeStyle() {
        return messageTimeStyle;
    }

    /**
     * @param m
     * @return
     */
    public IrcNotificationLevel getNotificationLevel(IrcMessage m) {
        if (m.isMeNamed() && shouldPlaySoundOnNamingMe()) {
            return IrcNotificationLevel.ME_NAMED;
        } else if (!m.isFromMe() && m.getSender() != null
                && shouldPlaySoundOnMessageFromNick(m.getSender().getNick())) {
            return IrcNotificationLevel.UNREAD_MESSAGES_FROM_A_TRACKED_USER;
        } else if (!m.isFromMe() && m.getUser() != null
                && shouldPlaySoundOnMessageInChannel(m.getLog().getChannel())) {
            return IrcNotificationLevel.UNREAD_MESSAGES;
        }
        return IrcNotificationLevel.NO_NOTIFICATION;
    }

    /**
     * @return
     */
    public ExtendedTextStyle getNotificationMessageStyle() {
        return notificationMessageStyle;
    }

    public Duration getPingInterval() {
        return DEFAULT_PING_INTERVAL;
    }

    public Duration getPingTimeout() {
        return COMMAND_TIMEOUT;
    }

    /**
     * @param message
     * @return
     */
    public IrcSearchMessageFormatter getSearchFormatter(PlainIrcMessage message) {
        return searchFormatter;
    }

    /**
     * Calls
     * {@link IPreferencesService#getString(String, String, String, org.eclipse.core.runtime.preferences.IScopeContext[])}
     * using {@link Plugin#ID} and a default ({@code null}) context order.
     *
     * @param key
     * @return
     */
    public String getString(PreferenceKey key) {
        IPreferenceStore store = EirccUi.getDefault().getPreferenceStore();
        return store.getString(key.toString());
        // return preferencesService.getString(EirccUi.PLUGIN_ID, , (String)
        // key.getDefaultValue(), null);
    }

    public ExtendedTextStyle getSystemMessageStyle() {
        return systemMessageStyle;
    }

    public ExtendedTextStyle getUserStyle(int index, boolean namingMe) {
        if (index < 0) {
            return null;
        }
        index %= userStylesNamingMe.length;
        return namingMe ? userStylesNamingMe[index] : userStyles[index];
    }

    public IrcUserStyler getUserStyler(int index) {
        index %= userStylers.length;
        return userStylers[index];
    }

    private Set<String> getWatchedChannels() {
        if (watchedChannels == null) {
            watchedChannels = new TreeSet<String>();
            String str = getString(PreferenceKey.WATCHED_CHANNELS);
            StringTokenizer st = new StringTokenizer(str, "\n\t\r" + WATCHED_OBJECT_DELIMITER);
            while (st.hasMoreTokens()) {
                String token = st.nextToken();
                watchedChannels.add(token);
            }
        }
        return watchedChannels;
    }

    private Map<String, Pattern> getWatchedNicks() {
        if (watchedNicks == null) {
            watchedNicks = new TreeMap<String, Pattern>();
            String str = getString(PreferenceKey.WATCHED_NICKS);
            StringTokenizer st = new StringTokenizer(str, "\n\t\r" + WATCHED_OBJECT_DELIMITER);
            while (st.hasMoreTokens()) {
                String nick = st.nextToken();
                watchedNicks.put(nick, Pattern.compile(nick));
            }
        }
        return watchedNicks;
    }

    /**
     * @param data
     * @return
     */
    public boolean isWatched(AbstractIrcChannel channel) {
        return channel != null && getWatchedChannels().contains(channel.getName());
    }

    /**
     * @param items
     */
    private void setCollection(PreferenceKey preferenceKey, Collection<String> items) {
        StringBuilder sb = new StringBuilder();
        for (String n : items) {
            if (sb.length() > 0) {
                sb.append(WATCHED_OBJECT_DELIMITER);
            }
            sb.append(n);
        }
        setString(preferenceKey, sb.toString());
    }

    public void setString(PreferenceKey key, String value) {
        IPreferenceStore store = EirccUi.getDefault().getPreferenceStore();
        store.setValue(key.toString(), value);
        // InstanceScope.INSTANCE.getNode(EirccUi.PLUGIN_ID).put();
    }

    /**
     * @param level
     * @return
     */
    public boolean shouldPlaySoundForMessage(IrcMessage m) {
        switch (m.getNotificationLevel()) {
        case NO_NOTIFICATION:
            return false;
        case UNREAD_MESSAGES:
            return shouldPlaySoundOnMessageInChannel(m.getLog().getChannel());
        case UNREAD_MESSAGES_FROM_A_TRACKED_USER:
            return shouldPlaySoundOnMessageFromNick(m.getNick());
        case ME_NAMED:
            return shouldTrayFlashOnNamingMe();
        default:
            return false;
        }
    }

    /**
     * @param user
     * @return
     */
    public boolean shouldPlaySoundOnMessageFromNick(String nick) {
        if (nick != null) {
            for (Pattern pattern : getWatchedNicks().values()) {
                if (pattern.matcher(nick).matches()) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * @param channel
     * @return
     */
    private boolean shouldPlaySoundOnMessageInChannel(AbstractIrcChannel channel) {
        return getWatchedChannels().contains(channel.getName());
    }

    /**
     * @return
     */
    public boolean shouldPlaySoundOnNamingMe() {
        return true;
    }

    /**
     * @return
     */
    public boolean shouldTrayFlashOnNamingMe() {
        return true;
    }

    /**
     * @return
     */
    public String showAddNickPatternDialog(String initialValue) {
        if (initialValue == null) {
            initialValue = "";
        }
        InputDialog dialog = new InputDialog(Display.getCurrent().getActiveShell(),
                IrcUiMessages.IrcNotificationsPreferencePage_addNickPatternTitle,
                IrcUiMessages.IrcNotificationsPreferencePage_addNickPatternText, initialValue, PATTERN_VALIDATOR);
        if (dialog.open() == Window.OK) {
            return dialog.getValue();
        }
        return null;
    }

}