<commit_before>/*******************************************************************************
 * Copyright (c) 2010 Oak Ridge National Laboratory.
 *  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.csstudio.alarm.beast.ui.alarmtable;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.regex.Pattern;

import org.csstudio.alarm.beast.client.AlarmTreeItem;
import org.csstudio.alarm.beast.client.AlarmTreePV;
import org.csstudio.alarm.beast.client.AlarmTreeRoot;
import org.csstudio.alarm.beast.client.GUIUpdateThrottle;
import org.csstudio.alarm.beast.ui.AuthIDs;
import org.csstudio.alarm.beast.ui.ContextMenuHelper;
import org.csstudio.alarm.beast.ui.SelectionHelper;
import org.csstudio.alarm.beast.ui.SeverityColorProvider;
import org.csstudio.alarm.beast.ui.actions.AlarmPerspectiveAction;
import org.csstudio.alarm.beast.ui.actions.ConfigureItemAction;
import org.csstudio.alarm.beast.ui.actions.DisableComponentAction;
import org.csstudio.alarm.beast.ui.clientmodel.AlarmClientModel;
import org.csstudio.alarm.beast.ui.clientmodel.AlarmClientModelListener;
import org.csstudio.apputil.text.RegExHelper;
import org.csstudio.security.SecuritySupport;
import org.csstudio.ui.util.MinSizeTableColumnLayout;
import org.csstudio.ui.util.dnd.ControlSystemDragSource;
import org.csstudio.ui.util.helpers.ComboHistoryHelper;
import org.csstudio.utility.singlesource.SingleSourcePlugin;
import org.csstudio.utility.singlesource.UIHelper.UI;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPartSite;

/** Alarm table GUI
 *
 *  @author <NAME>
 *  @author <NAME> - Combined/split alarm tables, configurable columns, filtering, blinking
 */
public class GUI extends Composite implements AlarmClientModelListener
{
    /**
     * <code>Blinker</code> is a singleton responsible for synchronous blinking of icons
     * on all existing alarm tables.
     *
     * @author <a href="mailto:<EMAIL>"><NAME></a>
     *
     */
    private static enum Blinker
    {
        INSTANCE;

        private final int period = Preferences.getBlinkingPeriod();
        private final Set<GUI> guis = Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<>()));
        private final Display display = Display.getDefault();
        private boolean active = false;

        void blink()
        {
            display.timerExec(period, ()->
            {
                if (active)
                {
                    for (GUI g : guis)
                    {
                        //if the GUI thread is this thread, blink on this thread,
                        //otherwise delegate to the GUI's thread and wait for it to finish
                        if (display == g.display)
                            g.blink();
                        else
                            g.display.syncExec(() -> g.blink());
                    }
                    blink();
                }
            });
        }
        void reset()
        {
            display.syncExec(() ->
            {
                for (GUI g : guis)
                    g.icon_provider.reset();
            });
        }
        void add(GUI gui)
        {
            display.syncExec(() ->
            {
                guis.add(gui);
                //when a new gui is added, always reset everything so that all tables are synchronised
                reset();
                if (!active)
                {
                    active = true;
                    blink();
                }
            });
        }
        void remove(GUI gui)
        {
            display.syncExec(() ->
            {
                guis.remove(gui);
                if (guis.isEmpty())
                    active = false;
            });
        }
    }

    /**<commit_msg>Bugfix for RAP.<commit_after>/*******************************************************************************
 * Copyright (c) 2010 Oak Ridge National Laboratory.
 *  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.csstudio.alarm.beast.ui.alarmtable;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.regex.Pattern;

import org.csstudio.alarm.beast.client.AlarmTreeItem;
import org.csstudio.alarm.beast.client.AlarmTreePV;
import org.csstudio.alarm.beast.client.AlarmTreeRoot;
import org.csstudio.alarm.beast.client.GUIUpdateThrottle;
import org.csstudio.alarm.beast.ui.AuthIDs;
import org.csstudio.alarm.beast.ui.ContextMenuHelper;
import org.csstudio.alarm.beast.ui.SelectionHelper;
import org.csstudio.alarm.beast.ui.SeverityColorProvider;
import org.csstudio.alarm.beast.ui.actions.AlarmPerspectiveAction;
import org.csstudio.alarm.beast.ui.actions.ConfigureItemAction;
import org.csstudio.alarm.beast.ui.actions.DisableComponentAction;
import org.csstudio.alarm.beast.ui.clientmodel.AlarmClientModel;
import org.csstudio.alarm.beast.ui.clientmodel.AlarmClientModelListener;
import org.csstudio.apputil.text.RegExHelper;
import org.csstudio.security.SecuritySupport;
import org.csstudio.ui.util.MinSizeTableColumnLayout;
import org.csstudio.ui.util.dnd.ControlSystemDragSource;
import org.csstudio.ui.util.helpers.ComboHistoryHelper;
import org.csstudio.utility.singlesource.SingleSourcePlugin;
import org.csstudio.utility.singlesource.UIHelper.UI;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPartSite;

/** Alarm table GUI
 *
 *  @author <NAME>
 *  @author <NAME> - Combined/split alarm tables, configurable columns, filtering, blinking
 */
public class GUI extends Composite implements AlarmClientModelListener
{
    /**
     * <code>Blinker</code> is a singleton responsible for synchronous blinking of icons
     * on all existing alarm tables.
     *
     * @author <a href="mailto:<EMAIL>"><NAME></a>
     *
     */
    private static enum Blinker
    {
        INSTANCE;

        private final int period = Preferences.getBlinkingPeriod();
        private final Set<GUI> guis = Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<>()));
        private final Display display = Display.getDefault();
        private boolean active = false;

        void blink()
        {
            if (!display.isDisposed())
            {
                display.timerExec(period, ()->
                {
                    if (active)
                    {
                        for (GUI g : guis)
                        {
                            //if the GUI thread is this thread, blink on this thread,
                            //otherwise delegate to the GUI's thread and wait for it to finish
                            if (display == g.display)
                                g.blink();
                            else if (!g.display.isDisposed())
                                g.display.syncExec(() -> g.blink());
                        }
                        blink();
                    }
                });
            }
        }
        void reset()
        {
            if (!display.isDisposed())
            {
                display.syncExec(() ->
                {
                    for (GUI g : guis)
                        g.icon_provider.reset();
                });
            }
        }
        void add(GUI gui)
        {
            if (!display.isDisposed())
            {
                display.syncExec(() ->
                {
                    guis.add(gui);
                    //when a new gui is added, always reset everything so that all tables are synchronised
                    reset();
                    if (!active)
                    {
                        active = true;
                        blink();
                    }
                });
            }
        }
        void remove(GUI gui)
        {
            if (!display.isDisposed())
            {
                display.syncExec(() ->
                {
                    guis.remove(gui);
                    if (guis.isEmpty())
                        active = false;
                });
            }
        }
    }

    /**
{'fraction_non_alphanumeric': 0.12521767974127207, 'fraction_numerical': 0.0013268098515631479, 'mean_word_length': 2.518086347724621, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '146808', 'n_tokens_mistral': 3538, 'n_tokens_neox': 3408, 'n_words': 646}