<commit_before>﻿using SimpleMJPEGStreamViewer.Properties;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace SimpleMJPEGStreamViewer {
    public partial class MainForm : Form {

        readonly SimpleBindingList<VideoItem> videoList = new SimpleBindingList<VideoItem>();
        readonly SynchronizationContext sync;

        const string defaultCamFile = "default.xml";

        public MainForm() {
            InitializeComponent();

            this.Icon = Icon.FromHandle(Resources.cam.GetHicon());

            sync = SynchronizationContext.Current;

            dataGridView1.AutoGenerateColumns = false;

            IEnumerable<DataGridViewRow> sel = null;

            dataGridView1.SaveSelection = columnIndex => {
                sel = columnIndex == PlayingColumn.Index || columnIndex == VisibleColumn.Index ? dataGridView1.SelectedRows.OfType<DataGridViewRow>() : null;
            };

            dataGridView1.RestoreSelection += () => {
                if(sel != null) {
                    foreach(var row in sel)
                        row.Selected = true;
                }
            };

            dataGridView1.SelectionChanged += (s, e) => {
                propertyGrid1.SelectedObjects = selectedItems.ToArray();
            };

            dataGridView1.DataSource = videoList;
            videoList.ListChanged += VideoList_ListChanged;
            videoList.BeforeRemove += VideoList_BeforeRemove;

            if(File.Exists(defaultCamFile)) {
                loadCams(defaultCamFile);
            }

            this.Disposed += (s, e) => {
                clearVideoList(); ;
            };
        }

        private void VideoList_BeforeRemove(object sender, VideoItem item) {
            item.Playing = false;
            var ctl = simpleLayoutPanel1.Controls[item.UUID.ToString()];
            if(ctl != null)
                ctl.Dispose();
        }

        void adaptProperties(VideoItem item, string propertyName = null) {
            var byPass = propertyName == null;
            if(propertyName == "Visible" || byPass) {
                simpleLayoutPanel1.Controls[item.UUID.ToString()].Visible = item.Visible;
            }

            if(propertyName == "Playing" || byPass) {
                if(item.Playing) {
                    var pb = (SimplePictureBox)simpleLayoutPanel1.Controls[item.UUID.ToString()];
                    Task.Run(() => startVideoAsync(pb, item));
                }
            }
        }

        void VideoList_ListChanged(object sender, ListChangedEventArgs e) {
            if(e.ListChangedType == ListChangedType.ItemAdded) {<commit_msg>Improved PropertyGrid refresh somehow<commit_after>﻿using SimpleMJPEGStreamViewer.Properties;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace SimpleMJPEGStreamViewer {
    public partial class MainForm : Form {

        readonly SimpleBindingList<VideoItem> videoList = new SimpleBindingList<VideoItem>();
        readonly SynchronizationContext sync;

        const string defaultCamFile = "default.xml";

        public MainForm() {
            InitializeComponent();

            this.Icon = Icon.FromHandle(Resources.cam.GetHicon());

            sync = SynchronizationContext.Current;

            dataGridView1.AutoGenerateColumns = false;

            IEnumerable<DataGridViewRow> sel = null;

            dataGridView1.SaveSelection = columnIndex => {
                sel = columnIndex == PlayingColumn.Index || columnIndex == VisibleColumn.Index ? dataGridView1.SelectedRows.OfType<DataGridViewRow>() : null;
            };

            dataGridView1.RestoreSelection += () => {
                if(sel != null) {
                    foreach(var row in sel)
                        row.Selected = true;
                }
            };

            dataGridView1.SelectionChanged += (s, e) => {
                propertyGrid1.SelectedObjects = selectedItems.ToArray();
            };

            dataGridView1.DataSource = videoList;
            videoList.ListChanged += VideoList_ListChanged;
            videoList.BeforeRemove += VideoList_BeforeRemove;

            if(File.Exists(defaultCamFile)) {
                loadCams(defaultCamFile);
            }

            this.Disposed += (s, e) => {
                clearVideoList(); ;
            };
        }

        private void VideoList_BeforeRemove(object sender, VideoItem item) {
            item.Playing = false;
            var ctl = simpleLayoutPanel1.Controls[item.UUID.ToString()];
            if(ctl != null)
                ctl.Dispose();
        }

        void adaptProperties(VideoItem item, string propertyName = null) {
            var byPass = propertyName == null;
            if(propertyName == "Visible" || byPass) {
                simpleLayoutPanel1.Controls[item.UUID.ToString()].Visible = item.Visible;
            }

            if(propertyName == "Playing" || byPass) {
                if(item.Playing) {
                    var pb = (SimplePictureBox)simpleLayoutPanel1.Controls[item.UUID.ToString()];
                    Task.Run(() => startVideoAsync(pb, item));
                }
            }

            if(propertyGrid1.SelectedObjects.Contains(item))
                propertyGrid1.Refresh();
        }

        void VideoList_ListChanged(object sender, ListChangedEventArgs e) {
            if(e.ListChangedType == ListChangedType.ItemAdded) {
{'fraction_non_alphanumeric': 0.0970873786407767, 'fraction_numerical': 0.0037472321580650655, 'mean_word_length': 2.0840336134453783, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '4720509', 'n_tokens_mistral': 1510, 'n_tokens_neox': 1436, 'n_words': 281}