public override ValidationResult Validate(
            object value, System.Globalization.CultureInfo cultureInfo)
        {
            DataGridEntry x = (value as BindingGroup).Items[0] as DataGridEntry;

            if (!FilterRules.IsValidRange(x.PortFirst, x.PortLast))
            {
                return(new ValidationResult(false, strings.wr_val_err_portrange_inval));
            }
            if (!FilterRules.IsValidAddress(x.Address))
            {
                return(new ValidationResult(false, strings.wr_val_err_address_inval));
            }
            if (!FilterRules.IsValidDescription(x.Description))
            {
                return(new ValidationResult(false, strings.wr_val_err_description_inval));
            }
            string action = FilterRules.Actions.GetCode(x.Action);

            if (!FilterRules.IsValidAction(action, x.KeyId))
            {
                if (action.Equals("encrypt"))
                {
                    return(new ValidationResult(false, strings.wr_val_err_keyid_inval));
                }
                else
                {
                    return(new ValidationResult(false, strings.wr_val_err_keyid_should_be_empty));
                }
            }
            return(ValidationResult.ValidResult);
        }
        /// <summary>
        /// Insert a new empty row, with a default description string
        /// </summary>
        /// <param name="index">position of the new row</param>
        private void InsertNewEntry(int index)
        {
            DataGridEntry dge = new DataGridEntry();

            // find the last description string matching the default template
            int lastnew = 0;

            foreach (var e in entries)
            {
                int n = 0;
                if (e.Description.Length >= strings.wr_prefix_new.Length + 3 &&
                    e.Description.StartsWith(strings.wr_prefix_new + " #"))
                {
                    if (int.TryParse(e.Description.Substring(
                                         strings.wr_prefix_new.Length + 2), out n))
                    {
                        if (lastnew < n)
                        {
                            lastnew = n;
                        }
                    }
                }
            }
            // fill description field with the next default value
            dge.Description = strings.wr_prefix_new + " #" + (1 + lastnew).ToString();
            entries.Insert(index, dge);
            RefreshMaskWarning();
        }
        /// <summary>
        /// Check whether a rule is masked by another (matches
        /// a subset of the other rule)
        /// </summary>
        /// <param name="cur">masked rule</param>
        /// <param name="prev">masking rule</param>
        /// <returns>true if cur is masked by prev</returns>
        private bool IsMaskedRule(DataGridEntry cur, DataGridEntry prev)
        {
            bool exeMasked = (prev.Executable.Length == 0 || prev.Executable.Equals(cur.Executable));

            int  curPortFirst, curPortLast, prevPortFirst, prevPortLast;
            bool portMasked = false;

            if (prev.PortFirst.Length == 0 && prev.PortLast.Length == 0)
            {
                portMasked = true;
            }
            else if (int.TryParse(cur.PortFirst, out curPortFirst) && int.TryParse(cur.PortLast, out curPortLast) &&
                     int.TryParse(prev.PortFirst, out prevPortFirst) && int.TryParse(prev.PortLast, out prevPortLast))
            {
                portMasked = !(prevPortLast <curPortFirst || prevPortFirst> curPortLast);
            }

            bool addressMasked = (prev.Address.Length == 0 || prev.Address.Equals(cur.Address));

            return(exeMasked && portMasked && addressMasked);
        }
        private void Window_Initialized(object sender, EventArgs e)
        {
            app = ((App)Application.Current);
            // bind action names as the action cell choices
            Action.ItemsSource = FilterRules.Actions.Names;

            entries          = new ObservableCollection <DataGridEntry>();
            this.DataContext = this;

            // populate the context menu to show on right mouse click on the data grid
            GridMenu = new ContextMenu();
            {
                MenuItem m = new MenuItem();
                m.Header = strings.wr_insert_before;
                m.Click += new RoutedEventHandler(dataGridMenuInsertBefore_Click);
                GridMenu.Items.Add(m);
            }
            {
                MenuItem m = new MenuItem();
                m.Header = strings.wr_insert_after;
                m.Click += new RoutedEventHandler(dataGridMenuInsertAfter_Click);
                GridMenu.Items.Add(m);
            }
            {
                MenuItem m = new MenuItem();
                m.Header = strings.wr_delete;
                m.Click += new RoutedEventHandler(dataGridMenuDelete_Click);
                GridMenu.Items.Add(m);
            }
            dataGrid.ContextMenu = GridMenu;

            // read filter rules from the configuration file
            FilterRules fl = new FilterRules();

            fl.Read();

            // populate the data grid
            foreach (var rule in fl.conf.Rules)
            {
                DataGridEntry dge    = new DataGridEntry();
                string        action = NullToEmpty(rule.Action);
                dge.Action      = FilterRules.Actions.GetName(action);
                dge.Address     = NullToEmpty(rule.Address);
                dge.Description = NullToEmpty(rule.Description);
                dge.Executable  = NullToEmpty(rule.ExePath);
                dge.KeyId       = NullToEmpty(rule.KeyId);
                dge.PortFirst   = NullToEmpty(rule.PortFirst);
                dge.PortLast    = NullToEmpty(rule.PortLast);
                entries.Add(dge);
            }

            // restore form's last state
            this.Top    = Properties.Settings.Default.Location.Top;
            this.Left   = Properties.Settings.Default.Location.Left;
            this.Width  = Properties.Settings.Default.Location.Width;
            this.Height = Properties.Settings.Default.Location.Height;
            if (Properties.Settings.Default.State != WindowState.Minimized)
            {
                this.WindowState = Properties.Settings.Default.State;
            }

            // bind validation rules to the data grid
            FilterValidationRule validationRule = new FilterValidationRule();

            validationRule.ValidationStep = ValidationStep.UpdatedValue;
            dataGrid.RowValidationRules.Add(validationRule);

            dragHelper = new DataGridDragHelper(gridRoot, popupDrag, popupDragText, dataGrid);

            this.Icon = app.icon;
        }