<commit_before>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace MultiSelectionTreeView
{
    public enum SelectionModalities
    {
        SingleSelectionOnly,
        MultipleSelectionOnly,
        KeyboardModifiersMode
    }

    public class SelectedItemsCollection : ObservableCollection<MultipleSelectionTreeViewItem> { }

    public class MultipleSelectionTreeView : ItemsControl
    {
        #region Properties
        private MultipleSelectionTreeViewItem _lastClickedItem = null;
        private SelectedItemsCollection _selectedItemsViewModels;

        public SelectionModalities SelectionMode
        {
            get { return (SelectionModalities)GetValue(SelectionModeProperty); }
            set { SetValue(SelectionModeProperty, value); }
        }
        public static readonly DependencyProperty SelectionModeProperty =
            DependencyProperty.Register("SelectionMode", typeof(SelectionModalities), typeof(MultipleSelectionTreeView), new UIPropertyMetadata(SelectionModalities.SingleSelectionOnly));

        public SelectedItemsCollection SelectedItemsViewModels
        {
            get { return _selectedItemsViewModels; }
            set
            {
                _selectedItemsViewModels = value;
                UpdateSelectedItems();
            }
        }

        private static readonly DependencyPropertyKey SelectedItemsPropertyKey =
            DependencyProperty.RegisterReadOnly("SelectedItems", typeof(ObservableCollection<object>), typeof(MultipleSelectionTreeView), new PropertyMetadata(new ObservableCollection<object>()));

        public static readonly DependencyProperty SelectedItemsProperty = SelectedItemsPropertyKey.DependencyProperty;

        public ObservableCollection<object> SelectedItems
        {
            get { return (ObservableCollection<object>)GetValue(SelectedItemsProperty); }
            set { SetValue(SelectedItemsProperty, value); }
        }
        #endregion

        #region Constructors
        static MultipleSelectionTreeView()
        {
            DefaultStyleKeyProperty.OverrideMetadata(
                    typeof(MultipleSelectionTreeView), new FrameworkPropertyMetadata(typeof(MultipleSelectionTreeView)));
        }

        public MultipleSelectionTreeView()
        {
            SelectedItemsViewModels = new SelectedItemsCollection();
            SelectedItemsViewModels.CollectionChanged += (sender, args) => UpdateSelectedItems();

            DependencyPropertyDescriptor
                .FromProperty(ItemsSourceProperty, typeof(ItemsControl))
                .AddValueChanged(this, (s, e) => ClearSelectedItems());
        }

        private void ClearSelectedItems()
        {
            SelectedItems.Clear();
            SelectedItemsViewModels.Clear();
        }
        #endregion

        private void UpdateSelectedItems()
        {
            SelectedItems.Clear();

            foreach (var selectedItemData in SelectedItemsViewModels.Select(x => x.DataContext))
            {
                SelectedItems.Add(selectedItemData);
            }
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new MultipleSelectionTreeViewItem();
        }

        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is MultipleSelectionTreeViewItem;
        }

        internal void OnSelectionChanges(MultipleSelectionTreeViewItem viewItem)
        {
            MultipleSelectionTreeViewItem newItem = viewItem;
            if (newItem == null)
                return;

            if (viewItem.IsSelectable && viewItem.IsSelected)
                AddItemToSelection(viewItem);
            else
                RemoveItemFromSelection(viewItem);
        }

        internal void OnViewItemMouseDown(MultipleSelectionTreeViewItem viewItem)
        {
            MultipleSelectionTreeViewItem newItem = viewItem;
            if (newItem == null)
                return;
            
            switch (this.SelectionMode)
            {
                case SelectionModalities.MultipleSelectionOnly:
                    ManageCtrlSelection(newItem);
                    break;
                case SelectionModalities.SingleSelectionOnly:
                    ManageSingleSelection(newItem);
                    SetLastClicked(viewItem);
                    break;
                case SelectionModalities.KeyboardModifiersMode:
                    if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
                    {
                        ManageShiftSelection(viewItem);
                    }
                    else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
                    {
                        ManageCtrlSelection(newItem);
                    }
                    else
                    {
                        ManageSingleSelection(newItem);
                        SetLastClicked(newItem);
                    }
                    break;
            }
        }

        private void SetLastClicked(MultipleSelectionTreeViewItem viewItem)
        {
            _lastClickedItem = viewItem.IsSelected ? viewItem : null;
        }

        public void OnItemDrop(MultipleSelectionTreeViewItem sourceItem, MultipleSelectionTreeViewItem targetItem)
        {
            foreach (var selectedItem in SelectedItemsViewModels)
            {
                var targetParentItems = (IList)targetItem.ItemsSource;
                targetParentItems.Add(selectedItem.DataContext);

                var sourceParentItems = (IList)selectedItem.ParentMultipleSelectionTreeViewItem.ItemsSource;
                sourceParentItems.Remove(selectedItem.DataContext);
            }

            SelectedItemsViewModels.Clear();
        }

        #region Methods
        public void UnselectAll()
        {
            if (Items != null && Items.Count > 0)
            {
                foreach (var item in Items)
                {
                    if (item is MultipleSelectionTreeViewItem)
                    {<commit_msg>Changed so that dropped items get at top of list<commit_after>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace MultiSelectionTreeView
{
    public enum SelectionModalities
    {
        SingleSelectionOnly,
        MultipleSelectionOnly,
        KeyboardModifiersMode
    }

    public class SelectedItemsCollection : ObservableCollection<MultipleSelectionTreeViewItem> { }

    public class MultipleSelectionTreeView : ItemsControl
    {
        #region Properties
        private MultipleSelectionTreeViewItem _lastClickedItem = null;
        private SelectedItemsCollection _selectedItemsViewModels;

        public SelectionModalities SelectionMode
        {
            get { return (SelectionModalities)GetValue(SelectionModeProperty); }
            set { SetValue(SelectionModeProperty, value); }
        }
        public static readonly DependencyProperty SelectionModeProperty =
            DependencyProperty.Register("SelectionMode", typeof(SelectionModalities), typeof(MultipleSelectionTreeView), new UIPropertyMetadata(SelectionModalities.SingleSelectionOnly));

        public SelectedItemsCollection SelectedItemsViewModels
        {
            get { return _selectedItemsViewModels; }
            set
            {
                _selectedItemsViewModels = value;
                UpdateSelectedItems();
            }
        }

        private static readonly DependencyPropertyKey SelectedItemsPropertyKey =
            DependencyProperty.RegisterReadOnly("SelectedItems", typeof(ObservableCollection<object>), typeof(MultipleSelectionTreeView), new PropertyMetadata(new ObservableCollection<object>()));

        public static readonly DependencyProperty SelectedItemsProperty = SelectedItemsPropertyKey.DependencyProperty;

        public ObservableCollection<object> SelectedItems
        {
            get { return (ObservableCollection<object>)GetValue(SelectedItemsProperty); }
            set { SetValue(SelectedItemsProperty, value); }
        }
        #endregion

        #region Constructors
        static MultipleSelectionTreeView()
        {
            DefaultStyleKeyProperty.OverrideMetadata(
                    typeof(MultipleSelectionTreeView), new FrameworkPropertyMetadata(typeof(MultipleSelectionTreeView)));
        }

        public MultipleSelectionTreeView()
        {
            SelectedItemsViewModels = new SelectedItemsCollection();
            SelectedItemsViewModels.CollectionChanged += (sender, args) => UpdateSelectedItems();

            DependencyPropertyDescriptor
                .FromProperty(ItemsSourceProperty, typeof(ItemsControl))
                .AddValueChanged(this, (s, e) => ClearSelectedItems());
        }

        private void ClearSelectedItems()
        {
            SelectedItems.Clear();
            SelectedItemsViewModels.Clear();
        }
        #endregion

        private void UpdateSelectedItems()
        {
            SelectedItems.Clear();

            foreach (var selectedItemData in SelectedItemsViewModels.Select(x => x.DataContext))
            {
                SelectedItems.Add(selectedItemData);
            }
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new MultipleSelectionTreeViewItem();
        }

        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is MultipleSelectionTreeViewItem;
        }

        internal void OnSelectionChanges(MultipleSelectionTreeViewItem viewItem)
        {
            MultipleSelectionTreeViewItem newItem = viewItem;
            if (newItem == null)
                return;

            if (viewItem.IsSelectable && viewItem.IsSelected)
                AddItemToSelection(viewItem);
            else
                RemoveItemFromSelection(viewItem);
        }

        internal void OnViewItemMouseDown(MultipleSelectionTreeViewItem viewItem)
        {
            MultipleSelectionTreeViewItem newItem = viewItem;
            if (newItem == null)
                return;
            
            switch (this.SelectionMode)
            {
                case SelectionModalities.MultipleSelectionOnly:
                    ManageCtrlSelection(newItem);
                    break;
                case SelectionModalities.SingleSelectionOnly:
                    ManageSingleSelection(newItem);
                    SetLastClicked(viewItem);
                    break;
                case SelectionModalities.KeyboardModifiersMode:
                    if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
                    {
                        ManageShiftSelection(viewItem);
                    }
                    else if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
                    {
                        ManageCtrlSelection(newItem);
                    }
                    else
                    {
                        ManageSingleSelection(newItem);
                        SetLastClicked(newItem);
                    }
                    break;
            }
        }

        private void SetLastClicked(MultipleSelectionTreeViewItem viewItem)
        {
            _lastClickedItem = viewItem.IsSelected ? viewItem : null;
        }

        public void OnItemDrop(MultipleSelectionTreeViewItem sourceItem, MultipleSelectionTreeViewItem targetItem)
        {
            foreach (var selectedItem in SelectedItemsViewModels)
            {
                var dataContext = selectedItem.DataContext;

                var sourceParentItems = (IList)selectedItem.ParentMultipleSelectionTreeViewItem.ItemsSource;
                sourceParentItems.Remove(dataContext);

                var targetParentItems = (IList)targetItem.ItemsSource;
                targetParentItems.Insert(0, dataContext);
            }

            SelectedItemsViewModels.Clear();
        }

        #region Methods
        public void UnselectAll()
        {
            if (Items != null && Items.Count > 0)
            {
                foreach (var item in Items)
                {
                    if (item is MultipleSelectionTreeViewItem)
                    {
{'fraction_non_alphanumeric': 0.06167400881057269, 'fraction_numerical': 0.00023599748269351794, 'mean_word_length': 2.0247442303116823, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '973535', 'n_tokens_mistral': 2876, 'n_tokens_neox': 2671, 'n_words': 527}