Esempio n. 1
0
 public void BeforePropertyChanged(IDataRecord record, string name, object previousValue, object nextValue)
 {
     if (IsUndoRedo)
     {
         return;
     }
     if (CurrentUndoGroupId == null || record is UndoItem || record is RedoItem)
     {
         return;
     }
     try
     {
         var undoItem = new UndoItem();
         undoItem.Time         = DateTime.Now;
         undoItem.Group        = CurrentUndoGroupId;
         undoItem.DataRecordId = record.Identifier;
         undoItem.Data         = InvertJsonExtensions.SerializeObject(record).ToString();
         undoItem.RecordType   = record.GetType().AssemblyQualifiedName;
         undoItem.Type         = UndoType.Changed;
         undoItem.Name         = CurrentName;
         UndoItems.Add(undoItem);
     }
     catch (Exception ex)
     {
     }
 }
Esempio n. 2
0
        public void AcceptScore(DartGameParameters parameters)
        {
            var currentPlayer = parameters.Players[parameters.CurrentPlayer];

            var undoItem = new UndoItem
            {
                Score            = currentPlayer.CurrentScore,
                CurrentDartCount = currentPlayer.CurrentDartCount - currentPlayer.LastDarts.Count,
            };

            currentPlayer.UndoItems.Add(undoItem);

            if (parameters.IsBust)
            {
                // If player busts then no value is recorded
                currentPlayer.RemoveDartScores();
                currentPlayer.InterimScore = parameters.Players[parameters.CurrentPlayer].CurrentScore;
            }

            currentPlayer.MergeLastDarts(false, new Leg
            {
                Id       = parameters.CurrentGameId,
                IsWinner = parameters.IsGameOver
            }, parameters.CurrentTurn);

            if (!parameters.IsBust)
            {
                parameters.Players[parameters.CurrentPlayer].CurrentScore -= parameters.DartTotal;
            }
        }
Esempio n. 3
0
    static public void Redo(GameObject _gO)
    {
        m_undoPos++;
        UndoItem uItem = m_undoObjects[m_undoPos - 1];

        _gO = uItem.GetObj();

        if (_gO.GetComponent <Rigidbody>() == null)
        {
            if (_gO.activeSelf)
            {
                _gO.SetActive(false);
            }
            else
            {
                _gO.SetActive(true);
            }

            return;
        }

        Vector2 temp = _gO.transform.position;

        _gO.transform.SetPositionAndRotation(new Vector3(uItem.GetPos().x, uItem.GetPos().y, 0), Quaternion.identity);
        uItem.SetPos(temp);

        if (_gO.layer == LayerMask.NameToLayer("Path"))
        {
            LineScript.ModifyLine(_gO);
        }
    }
Esempio n. 4
0
 private void ApplyUndoItem(UndoItem i)
 {
     lastChar.ShowTimeLeft = 0;
     Text.Text             = i.Value;
     CaretPos.TextPos      = i.TextPos;
     CaretPos.InvalidatePreservingTextPos();
 }
        private void Do(string text, int position)
        {
            if (stateLocked != IntPtr.Zero)
            {
                return;
            }

            UndoItem ua = new UndoItem(text, position, new Point(HScrollPos, VScrollPos));

            UndoList.RemoveRange(UndoIndex, UndoList.Count - UndoIndex);
            UndoList.Add(ua);
            if (UndoList.Count > UNDO_BUFFER)
            {
                UndoList.RemoveAt(0);
            }

            // make undo/redo a little smarter, remove single strokes
            // reducing nr of undo states
            if (UndoList.Count > 7)
            {
                bool     canRemove = true;
                UndoItem nextItem  = ua;
                for (int i = 0; i < 6; i++)
                {
                    UndoItem prevItem = UndoList[UndoList.Count - 2 - i];
                    canRemove &= (Math.Abs(prevItem.Text.Length - nextItem.Text.Length) <= 1 && Math.Abs(prevItem.Position - nextItem.Position) <= 1);
                    nextItem   = prevItem;
                }
                if (canRemove)
                {
                    UndoList.RemoveRange(UndoList.Count - 6, 5);
                }
            }
            UndoIndex = UndoList.Count;
        }
Esempio n. 6
0
        public void AcceptScore(DartGameParameters parameters)
        {
            var currentPlayer = parameters.Players[parameters.CurrentPlayer];

            var undoItem = new UndoItem
            {
                Score            = currentPlayer.CurrentScore,
                CurrentDartCount = currentPlayer.CurrentDartCount - currentPlayer.LastDarts.Count,
            };

            currentPlayer.UndoItems.Add(undoItem);

            undoItem.HitsBull = currentPlayer.OldHits.ContainsKey(25)
                ? currentPlayer.OldHits[25]
                : currentPlayer.HitsBull;

            undoItem.Hits20 = currentPlayer.OldHits.ContainsKey(20) ? currentPlayer.OldHits[20] : currentPlayer.Hits20;
            undoItem.Hits19 = currentPlayer.OldHits.ContainsKey(19) ? currentPlayer.OldHits[19] : currentPlayer.Hits19;
            undoItem.Hits18 = currentPlayer.OldHits.ContainsKey(18) ? currentPlayer.OldHits[18] : currentPlayer.Hits18;
            undoItem.Hits17 = currentPlayer.OldHits.ContainsKey(17) ? currentPlayer.OldHits[17] : currentPlayer.Hits17;
            undoItem.Hits16 = currentPlayer.OldHits.ContainsKey(16) ? currentPlayer.OldHits[16] : currentPlayer.Hits16;
            undoItem.Hits15 = currentPlayer.OldHits.ContainsKey(15) ? currentPlayer.OldHits[15] : currentPlayer.Hits15;

            currentPlayer.AcceptCricketScores();

            currentPlayer.CurrentScore += parameters.DartTotal;

            currentPlayer.MergeLastDarts(false, new Leg
            {
                Id       = parameters.CurrentGameId,
                IsWinner = parameters.IsGameOver
            }, parameters.CurrentTurn);

            CheckGamesState(parameters.Players);
        }
Esempio n. 7
0
 static bool CanBeCombined(UndoItem ui1, UndoItem ui2)
 {
     return
         (string.IsNullOrEmpty(ui2.Diff.Remove) &&
          ui1.SelectionInfoB.Length == 0 &&
          ui2.SelectionInfoA.Length == 0 &&
          ui1.SelectionInfoB.SelectionStart == ui2.SelectionInfoA.SelectionStart);
 }
Esempio n. 8
0
 public void Add(UndoItem item)
 {
     if (pause_count > 0 || undo_in_progress)
     {
         return;
     }
     UndoStack.Push(item);
 }
Esempio n. 9
0
 private bool FollowEachother(UndoItem first, UndoItem second)
 {
     if (first.editor != second.editor || first.type != second.type)
     {
         return(false);
     }
     return(GetEndPoint(first) == second.position);
 }
Esempio n. 10
0
 public void Undo()
 {
     // loop thru group items backwards
     for (int i = undoItems.Count - 1; i >= 0; i--)
     {
         UndoItem ui = undoItems[i] as UndoItem;
         _undo.Undoing = true;
         ui.Undo();
     }
 }
Esempio n. 11
0
        public void TextAdded(string text, MyEditor editor, TextPoint position)
        {
            updatedFiles.Remove(editor);
            if (text.Contains(";") || text.Contains("}"))
            {
                AddEditorSignal(editor);
            }

            redoList.Clear();
            //If this and the two previous can be joined into 1 token, join them in 1 undo (if they follow eachother)
            UndoItem item = new UndoItem(text, editor, position, UndoType.TextAdded);

            if (undoList.Count > 0)
            {
                UndoItem lastItem = undoList[undoList.Count - 1];
                if (FollowEachother(lastItem, item))
                {
                    string       joined = lastItem.text + item.text;
                    Lexer        lexer  = new Lexer(new StringReader(joined));
                    List <Token> tokens = new List <Token>();
                    while (!(lexer.Peek() is EOF))
                    {
                        tokens.Add(lexer.Next());
                    }
                    if (tokens.Count == 1 || tokens.All(elm => elm is TWhiteSpace))
                    {
                        lastItem.text += item.text;
                        item           = lastItem;

                        if (undoList.Count > 1)
                        {
                            lastItem = undoList[undoList.Count - 2];
                            if (FollowEachother(lastItem, item))
                            {
                                joined = lastItem.text + item.text;
                                lexer  = new Lexer(new StringReader(joined));
                                tokens = new List <Token>();
                                while (!(lexer.Peek() is EOF))
                                {
                                    tokens.Add(lexer.Next());
                                }
                                if (tokens.Count == 1 || tokens.All(elm => elm is TWhiteSpace))
                                {
                                    lastItem.text += item.text;
                                    undoList.RemoveAt(undoList.Count - 1);
                                }
                            }
                        }
                        return;
                    }
                }
            }
            undoList.Add(item);
        }
        private void RestoreState(UndoItem item)
        {
            Lock();
            // restore state
            Textbox.Rtf = item.Text;
            Textbox.Select(item.Position, 0);
            HScrollPos = item.ScrollPosition.X;
            VScrollPos = item.ScrollPosition.Y;

            Unlock();
        }
Esempio n. 13
0
        public void TextReplaced(string oldText, string newText, MyEditor editor, TextPoint position)
        {
            AddEditorSignal(editor);
            if (oldText == newText)
            {
                return;
            }
            UndoItem item = new UndoItem(oldText, editor, position, UndoType.TextReplaced);

            item.replaceNewText = newText;
            undoList.Add(item);
        }
Esempio n. 14
0
 public void Undo()
 {
     if (UndoStack.Count > 0)
     {
         UndoItem item = UndoStack.Pop();
         undo_in_progress = true;
         item.Undo(mainWindow);
         undo_in_progress = false;
     }
     else
     {
         Console.Beep(500, 500);
     }
 }
Esempio n. 15
0
        internal void undo()
        {
            UndoItem undoItem = null;

            if (_actions.Count == 0)
            {
                return;
            }

            undoItem = (UndoItem)_actions.Pop();

            _Undoing = true;
            undoItem.Undo();
        }
Esempio n. 16
0
    static public void AddToUndo(GameObject _gO, Vector2 _mousePos)
    {
        for (int i = 0; i < m_undoObjects.Count - m_undoPos; i++)
        {
            GameObject gO = m_undoObjects[m_undoObjects.Count - 1].GetObj();
            if (gO.layer == LayerMask.NameToLayer("Path"))
            {
                LineScript.AddToPathPool(gO);
            }
            m_undoObjects.RemoveAt(m_undoObjects.Count - 1);
        }

        m_undoPos++;
        UndoItem uItem = new UndoItem(_gO, _gO.transform.position);

        m_undoObjects.Add(uItem);
    }
Esempio n. 17
0
        private TextPoint GetEndPoint(UndoItem item)
        {
            TextPoint endPoint = new TextPoint(item.position.Line, item.position.Pos);

            foreach (char c in item.text)
            {
                if (c == '\n')
                {
                    endPoint = new TextPoint(endPoint.Line + 1, 0);
                }
                else
                {
                    endPoint.Pos++;
                }
            }
            return(endPoint);
        }
        public void Redo()
        {
            if (!CanRedo)
            {
                return;
            }

            UndoIndex++;
            if (UndoIndex > UndoList.Count)
            {
                UndoIndex = UndoList.Count;
            }

            UndoItem ua = UndoList[UndoIndex - 1];

            RestoreState(ua);
        }
        public void Undo()
        {
            if (!CanUndo)
            {
                return;
            }

            UndoIndex--;
            if (UndoIndex < 1)
            {
                UndoIndex = 1;
            }

            // implement undo action here
            UndoItem ua = UndoList[UndoIndex - 1];

            RestoreState(ua);
        }
Esempio n. 20
0
 protected void AddItem(eOperationType type, Object3d obj, double x, double y, double z)
 {
     if (obj == null)
         return;
     while (m_undopointer < m_undoItemList.Count)
     {
         m_undoItemList.RemoveAt(m_undopointer);
     }
     UndoItem item = new UndoItem();
     item.opType = type;
     item.obj = obj;
     item.x = x;
     item.y = y;
     item.z = z;
     item.linkedToPrev = false;
     m_undoItemList.Add(item);
     m_undopointer++;
     UpdateButtons();
 }
Esempio n. 21
0
    static public void AddToUndo(GameObject _gO)
    {
        int numOverUndo = m_undoObjects.Count - m_undoPos;

        for (int i = 0; i < numOverUndo; i++)
        {
            GameObject gO = m_undoObjects[m_undoObjects.Count - 1].GetObj();
            if (gO.layer == LayerMask.NameToLayer("Path"))
            {
                LineScript.AddToPathPool(gO);
            }
            m_undoObjects.RemoveAt(m_undoObjects.Count - 1);
        }

        m_undoPos++;
        UndoItem uItem = new UndoItem(_gO);

        m_undoObjects.Add(uItem);
    }
Esempio n. 22
0
        private void NodeChanged(object sender, XmlNodeChangedEventArgs e)
        {
            if (this._Undoing)
            {
                // if we're undoing ignore the event since it is the result of an undo
                _pState  = null;
                _Undoing = false;
                return;
            }

            UndoItem undo = null;

            switch (e.Action)
            {
            case XmlNodeChangedAction.Insert:
                undo = new NodeInsertedUndo(e, _pState);
                break;

            case XmlNodeChangedAction.Remove:
                undo = new NodeRemovedUndo(e, _pState);
                break;

            case XmlNodeChangedAction.Change:
                undo = new NodeChangedUndo(e, _pState);
                break;

            default:
                throw new Exception("Unknown Action");
            }
            _pState = null;
            if (_currentUndoGroup != null)
            {
                _currentUndoGroup.AddUndoItem(undo);
            }
            else if (GroupsOnly)
            {
                _pState = null;
            }
            else
            {
                _actions.Push(undo);
            }
        }
Esempio n. 23
0
        public void HandleTextChanged(TextChangedEventArgs e)
        {
            if (IsUndoOrRedo)
            {
                return;
            }

            var td = Rtb.GetTextData("\n");
            var si = new SelectionInfo(td.SelectionStart, td.SelectionEnd);
            var ui = new UndoItem
            {
                Diff           = GetDiff(PreviousText, td.Text),
                SelectionInfoA = PreviousSelection,
                SelectionInfoB = si,
            };

            // try combining
            bool combined = false;

            if (UndoList.Count > 1)              // (exclude the first initial one)
            {
                var last = UndoList.Last( );
                if (IsTrackingTextChange && CanBeCombined(last, ui))
                {
                    last.Diff.Add      += ui.Diff.Add;
                    last.SelectionInfoB = new SelectionInfo(td.SelectionStart, td.SelectionEnd);
                    combined            = true;
                }
            }

            if (!combined)
            {
                UndoList.Add(ui);
            }

            PreviousText      = td.Text;
            PreviousSelection = si;

            RedoList.Clear( );

            IsTrackingTextChange = true;
        }
Esempio n. 24
0
        public void RecordRemoved(IDataRecord record)
        {
            if (IsUndoRedo)
            {
                return;
            }
            if (CurrentUndoGroupId == null || record is UndoItem || record is RedoItem)
            {
                return;
            }
            var undoItem = new UndoItem();

            undoItem.Time         = DateTime.Now;
            undoItem.Group        = CurrentUndoGroupId;
            undoItem.DataRecordId = record.Identifier;
            undoItem.Data         = InvertJsonExtensions.SerializeObject(record).ToString();
            undoItem.RecordType   = record.GetType().AssemblyQualifiedName;
            undoItem.Name         = CurrentName;
            undoItem.Type         = UndoType.Removed;
            UndoItems.Add(undoItem);
        }
Esempio n. 25
0
        private void SaveUndo()
        {
            List <UndoItem> undo = new List <UndoItem>();

            foreach (Cell cell in _globalData.GameField)
            {
                if (!(cell.Obj is null))
                {
                    UndoItem     undoItem = new UndoItem();
                    SquareScript sq       = cell.Obj.GetComponent <SquareScript>();

                    undoItem.SquareColor     = sq.SquareColor;
                    undoItem.SquareDirection = sq.SquareDirection;
                    undoItem.xPos            = (int)cell.Obj.transform.position.x / Const.CellSizePx;
                    undoItem.yPos            = (int)cell.Obj.transform.position.y / Const.CellSizePx;

                    undo.Add(undoItem);
                }
            }
            _globalData.UndList.Push(undo);
        }
Esempio n. 26
0
        protected void AddItem(eOperationType type, Object3d obj, double x, double y, double z)
        {
            if (obj == null)
            {
                return;
            }
            while (m_undopointer < m_undoItemList.Count)
            {
                m_undoItemList.RemoveAt(m_undopointer);
            }
            UndoItem item = new UndoItem();

            item.opType       = type;
            item.obj          = obj;
            item.x            = x;
            item.y            = y;
            item.z            = z;
            item.linkedToPrev = false;
            m_undoItemList.Add(item);
            m_undopointer++;
            UpdateButtons();
        }
Esempio n. 27
0
        public void Redo()
        {
            while (m_undopointer < m_undoItemList.Count)
            {
                UndoItem item = m_undoItemList[m_undopointer];
                m_undopointer++;
                switch (item.opType)
                {
                case eOperationType.Translate:
                    item.obj.Translate((float)item.x, (float)item.y, (float)item.z);
                    break;

                case eOperationType.Rotate:
                    item.obj.Rotate((float)item.x, (float)item.y, (float)item.z);
                    break;

                case eOperationType.Scale:
                    item.obj.Scale((float)item.x, (float)item.y, (float)item.z);
                    break;

                case eOperationType.Add:
                    UVDLPApp.Instance().m_engine3d.AddObject(item.obj);
                    break;

                case eOperationType.Del:
                    UVDLPApp.Instance().m_engine3d.RemoveObject(item.obj);
                    break;
                }
                item.obj.Update();
                if ((m_undopointer < m_undoItemList.Count) &&
                    (m_undoItemList[m_undopointer].linkedToPrev == false))
                {
                    break;
                }
            }
            UVDLPApp.Instance().RaiseAppEvent(eAppEvent.eUpdateSelectedObject, "updateobject");
            UpdateButtons();
        }
Esempio n. 28
0
 public void Redo()
 {
     if (redoList.Count > 0)
     {
         UndoItem item = redoList[redoList.Count - 1];
         redoList.RemoveAt(redoList.Count - 1);
         undoList.Add(item);
         AddEditorSignal(item.editor);
         if (item.type == UndoType.TextAdded)
         {//Do the reversed
             item.editor.UndoInsert(item.position, item.text);
         }
         else if (item.type == UndoType.TextRemoved)
         {
             item.editor.UndoRemove(item.position, GetEndPoint(item));
         }
         else if (item.type == UndoType.TextReplaced)
         {
             item.editor.UndoRemove(item.position, GetEndPoint(item));
             item.editor.UndoInsert(item.position, item.replaceNewText);
         }
     }
 }
Esempio n. 29
0
        public void Undo()
        {
            while (m_undopointer > 0)
            {
                UndoItem item = m_undoItemList[m_undopointer - 1];
                m_undopointer--;
                switch (item.opType)
                {
                case eOperationType.Translate:
                    item.obj.Translate(-(float)item.x, -(float)item.y, -(float)item.z, false);
                    break;

                case eOperationType.Rotate:
                    item.obj.Rotate(-(float)item.x, -(float)item.y, -(float)item.z);
                    break;

                case eOperationType.Scale:
                    item.obj.Scale((float)(1.0 / item.x), (float)(1.0 / item.y), (float)(1.0 / item.z));
                    break;

                case eOperationType.Add:
                    UVDLPApp.Instance().m_engine3d.RemoveObject(item.obj);
                    break;

                case eOperationType.Del:
                    UVDLPApp.Instance().m_engine3d.AddObject(item.obj);
                    break;
                }
                item.obj.Update();
                if (item.linkedToPrev == false)
                {
                    break;
                }
            }
            UVDLPApp.Instance().RaiseAppEvent(eAppEvent.eUpdateSelectedObject, "updateobject");
            UpdateButtons();
        }
Esempio n. 30
0
 public void Submit(UndoItem op)
 {
     if (op.DoCommand())
     {
         _undoManager.AddUndoItem(op);
         _Modified = true;
     }
 }
Esempio n. 31
0
 internal void AddUndoItem(UndoItem ui)
 {
     undoItems.Add(ui);
 }
 private TextPoint GetEndPoint(UndoItem item)
 {
     TextPoint endPoint = new TextPoint(item.position.Line, item.position.Pos);
     foreach (char c in item.text)
     {
         if (c == '\n')
             endPoint = new TextPoint(endPoint.Line + 1, 0);
         else
             endPoint.Pos++;
     }
     return endPoint;
 }
 private bool FollowEachother(UndoItem first, UndoItem second)
 {
     if (first.editor != second.editor || first.type != second.type) return false;
     return GetEndPoint(first) == second.position;
 }
 public void TextReplaced(string oldText, string newText, MyEditor editor, TextPoint position)
 {
     AddEditorSignal(editor);
     if (oldText == newText) return;
     UndoItem item = new UndoItem(oldText, editor, position, UndoType.TextReplaced);
     item.replaceNewText = newText;
     undoList.Add(item);
 }
        public void TextRemoved(string text, MyEditor editor, TextPoint position)
        {
            AddEditorSignal(editor);

            redoList.Clear();
            //If this and the two previous can be joined into 1 token, join them in 1 undo (if they follow eachother)
            UndoItem item = new UndoItem(text, editor, position, UndoType.TextRemoved);
            if (undoList.Count > 0)
            {
                UndoItem lastItem = undoList[undoList.Count - 1];
                if (FollowEachother(item, lastItem))
                {
                    string joined = item.text + lastItem.text;
                    Lexer lexer = new Lexer(new StringReader(joined));
                    List<Token> tokens = new List<Token>();
                    while (!(lexer.Peek() is EOF))
                    {
                        tokens.Add(lexer.Next());
                    }
                    if (tokens.Count == 1 || tokens.All(elm => elm is TWhiteSpace))
                    {
                        lastItem.text = joined;
                        lastItem.position = item.position;
                        item = lastItem;

                        if (undoList.Count > 1)
                        {
                            lastItem = undoList[undoList.Count - 2];
                            if (FollowEachother(item, lastItem))
                            {
                                joined = item.text + lastItem.text;
                                lexer = new Lexer(new StringReader(joined));
                                tokens = new List<Token>();
                                while (!(lexer.Peek() is EOF))
                                {
                                    tokens.Add(lexer.Next());
                                }
                                if (tokens.Count == 1 || tokens.All(elm => elm is TWhiteSpace))
                                {
                                    lastItem.text = joined;
                                    lastItem.position = item.position;
                                    undoList.RemoveAt(undoList.Count - 1);
                                }
                            }
                        }
                        return;
                    }
                }
            }
            undoList.Add(item);
        }
Esempio n. 36
0
 public void AddUndoItem(UndoItem op)
 {
     undoStack.Push(op);
     redoStack.Clear();
 }
Esempio n. 37
0
File: Undo.cs Progetto: mnisl/OD
 internal void AddUndoItem(UndoItem ui)
 {
     undoItems.Add(ui);
 }
Esempio n. 38
0
 private void RestoreState(UndoItem item)
 {
     Lock();
     // restore state
     Textbox.Rtf = item.Text;
     Textbox.Select(item.Position, 0);
     HScrollPos = item.ScrollPosition.X;
     VScrollPos = item.ScrollPosition.Y;
     
     Unlock();
 }
Esempio n. 39
0
        private void Do(string text, int position)
        {
            
            if (stateLocked != IntPtr.Zero) return;

            UndoItem ua = new UndoItem(text, position, new Point(HScrollPos, VScrollPos));
            UndoList.RemoveRange(UndoIndex, UndoList.Count - UndoIndex);
            UndoList.Add(ua);
            if (UndoList.Count > UNDO_BUFFER)
                UndoList.RemoveAt(0);

            // make undo/redo a little smarter, remove single strokes
            // reducing nr of undo states
            if (UndoList.Count > 7)
            {
                bool canRemove = true;
                UndoItem nextItem = ua;
                for (int i = 0; i < 6; i++)
                {
                    UndoItem prevItem = UndoList[UndoList.Count - 2 - i];
                    canRemove &= (Math.Abs(prevItem.Text.Length - nextItem.Text.Length) <= 1 && Math.Abs(prevItem.Position - nextItem.Position) <= 1);
                    nextItem = prevItem;
                }
                if (canRemove)
                {
                    UndoList.RemoveRange(UndoList.Count - 6, 5);
                }
            }
            UndoIndex = UndoList.Count;
        }
        private static void ApplyToArea <TIn, TOut>(Range range, Func <TIn, TOut> transform)
        {
            var rangeValue = range.Value;

            if (rangeValue is null)
            {
                return;
            }

            if (rangeValue is TIn currentValue)
            {
                var newValue = transform(currentValue);
                range.Value = newValue;
                var undoItem = new UndoItem
                {
                    OldValue    = currentValue,
                    NewValue    = newValue,
                    ColumnIndex = range.Column,
                    RowIndex    = range.Row
                };
                undoManager.PushUndoItem(undoItem);
                return;
            }

            // minimize number of COM calls to excel
            if (!(rangeValue is object[,] values))
            {
                return;
            }

            int upperI = values.GetUpperBound(0);             // Rows
            int upperJ = values.GetUpperBound(1);             // Columns

            var isChanged = false;
            var oldValues = (object[, ])values.Clone();

            logger.Debug($"Converting columns from {values.GetLowerBound(0)} to {upperI}, " +
                         $"rows from {values.GetLowerBound(1)} to {upperJ}");

            for (int i = values.GetLowerBound(0); i <= upperI; i++)
            {
                for (int j = values.GetLowerBound(1); j <= upperJ; j++)
                {
                    var value = values[i, j];
                    if (value is TIn s)
                    {
                        var newValue = transform(s);
                        if ((object)newValue != value)                         // TODO check boxing time on million values
                        {
                            isChanged    = true;
                            values[i, j] = newValue;
                        }
                    }
                }
            }

            if (isChanged)
            {
                logger.Debug("Some values were converted, writing to worksheet");
                range.Value = values;
                undoManager.PushAreaUndoItem(new AreaUndoItems
                {
                    NewValues = values,
                    OldValues = oldValues,
                    Column    = range.Column,
                    Row       = range.Row,
                    Height    = upperI,
                    Width     = upperJ
                });
            }
        }