private void ShowMagicMenu(MouseEventArgs e, RobotGridItem robot, int rowIndex)
        {
            menuMagic.Items.Clear();

            var robotMagics = grid.GetBoundValues().Select(r => r.Robot.Magic).OrderBy(m => m).ToList();
            // след. незанятый Magic
            var nextMagic = robotMagics.Count == 0 ? 1 : robotMagics[robotMagics.Count - 1] + 1;

            // найти "дырку" в Magic-ах роботов
            var freeMagic = 0;

            if (robotMagics.Count == 1)
            {
                freeMagic = robotMagics[0] > 1 ? 1 : 0;
            }
            else if (robotMagics.Count > 1)
            {
                for (var j = 1; j < robotMagics.Count; j++)
                {
                    if (robotMagics[j] > (robotMagics[j - 1] + 1))
                    {
                        freeMagic = robotMagics[j - 1] + 1;
                        break;
                    }
                }
            }

            // сбросить Magic (снять флаг инициализации)
            if (LivePortfolioMode)
            {
                if (robot.Initialized)
                {
                    var menuReset = menuMagic.Items.Add(Localizer.GetString("TitleReset") + " Magic");
                    menuReset.Click += MagicReset;
                }
            }

            // сформировать меню Magic-ов
            var magics = new List <int>();

            if (freeMagic > 0)
            {
                magics.Add(freeMagic);
            }
            magics.Add(nextMagic);
            foreach (var magic in magics)
            {
                var item = menuMagic.Items.Add(magic.ToString());
                item.Click += MagicSelected;
            }
            menuMagic.Tag = rowIndex;
            // показать меню
            menuMagic.Show(gridRobot, e.X, e.Y);
        }
        private void ShowMagicMenu(MouseEventArgs e, RobotGridItem robot, int rowIndex)
        {
            menuMagic.Items.Clear();

            var robotMagics = grid.GetBoundValues().Select(r => r.Robot.Magic).OrderBy(m => m).ToList();
            // след. незанятый Magic
            var nextMagic = robotMagics.Count == 0 ? 1 : robotMagics[robotMagics.Count - 1] + 1;

            // найти "дырку" в Magic-ах роботов
            var freeMagic = 0;
            if (robotMagics.Count == 1)
            {
                freeMagic = robotMagics[0] > 1 ? 1 : 0;
            }
            else if (robotMagics.Count > 1)
            {
                for (var j = 1; j < robotMagics.Count; j++)
                {
                    if (robotMagics[j] > (robotMagics[j - 1] + 1))
                    {
                        freeMagic = robotMagics[j - 1] + 1;
                        break;
                    }
                }
            }

            // сбросить Magic (снять флаг инициализации)
            if (LivePortfolioMode)
            if (robot.Initialized)
            {
                var menuReset = menuMagic.Items.Add(Localizer.GetString("TitleReset") + " Magic");
                menuReset.Click += MagicReset;
            }

            // сформировать меню Magic-ов
            var magics = new List<int>();
            if (freeMagic > 0) magics.Add(freeMagic);
            magics.Add(nextMagic);
            foreach (var magic in magics)
            {
                var item = menuMagic.Items.Add(magic.ToString());
                item.Click += MagicSelected;
            }
            menuMagic.Tag = rowIndex;
            // показать меню
            menuMagic.Show(gridRobot, e.X, e.Y);
        }
        private void GridRobotUserHitCell(object sender, MouseEventArgs e, int rowIndex, FastColumn col, RobotGridItem gridItem)
        {
            var robot = gridItem.Robot;

            // показать меню выбора Magic-a,
            // подсветить в первую очередь, незанятые номера
            if (col.PropertyName == RobotGridItem.speciman.Property(p => p.Magic) && e.Button == MouseButtons.Left)
            {
                ShowMagicMenu(e, gridItem, rowIndex);
                return;
            }

            // показать окно настройки тикеров для робота
            if (col.PropertyName == RobotGridItem.speciman.Property(p => p.HumanRTickers) && e.Button == MouseButtons.Left)
            {
                var dlg = new RobotTimeframesForm(robot.Graphics);
                if (dlg.ShowDialog() != DialogResult.OK) return;
                robot.Graphics = dlg.UpdatedGraphics;
                gridRobot.UpdateRow(rowIndex, gridItem);
                gridRobot.InvalidateCell(col, rowIndex);
                return;
            }

            // настроить робота
            if ((/*col.PropertyName == "TypeName" || */e.Clicks > 1) && e.Button == MouseButtons.Left)
            {
                ShowRobotParamsDialog(robot);
            }
        }
        private void GridRobotUserHitCell(object sender, MouseEventArgs e, int rowIndex, FastColumn col, RobotGridItem gridItem)
        {
            var robot = gridItem.Robot;

            // показать меню выбора Magic-a,
            // подсветить в первую очередь, незанятые номера
            if (col.PropertyName == RobotGridItem.speciman.Property(p => p.Magic) && e.Button == MouseButtons.Left)
            {
                ShowMagicMenu(e, gridItem, rowIndex);
                return;
            }

            // показать окно настройки тикеров для робота
            if (col.PropertyName == RobotGridItem.speciman.Property(p => p.HumanRTickers) && e.Button == MouseButtons.Left)
            {
                var dlg = new RobotTimeframesForm(robot.Graphics);
                if (dlg.ShowDialog() != DialogResult.OK)
                {
                    return;
                }
                robot.Graphics = dlg.UpdatedGraphics;
                gridRobot.UpdateRow(rowIndex, gridItem);
                gridRobot.InvalidateCell(col, rowIndex);
                return;
            }

            // настроить робота
            if ((/*col.PropertyName == "TypeName" || */ e.Clicks > 1) && e.Button == MouseButtons.Left)
            {
                ShowRobotParamsDialog(robot);
            }
        }