Пример #1
0
        private void ExecutedHandler(object sender, ExecutedRoutedEventArgs e)
        {
            // При любой команде мержинг отменяется, мало ли что там команда навыполняла
            PushUndoAction(null, false);

            RichTextBox edit = (RichTextBox)sender;

            if (e.Command == EditingCommands.DeletePreviousWord ||
                e.Command == EditingCommands.DeleteNextWord)
            {
                if (!edit.Selection.IsEmpty)
                {
                    RemoveSelection(edit);
                }
                else
                {
                    int offsetFromEnd = edit.Document.ContentEnd.GetOffsetToPosition(edit.CaretPosition);
                    int offsetFromStart = edit.Document.ContentStart.GetOffsetToPosition(edit.CaretPosition);
                    TextPointer pointer = edit.CaretPosition;

                    if (e.Command == EditingCommands.DeletePreviousWord)
                    {
                        int resOffset = FindNextWhitespaceBackward(edit);

                        if (resOffset != -1)
                        {
                            TextRange range = new TextRange(
                                edit.Document.ContentStart.GetPositionAtOffset(resOffset),
                                edit.Document.ContentEnd.GetPositionAtOffset(offsetFromEnd));

                            PushUndoAction(new UndoBlockRemove(edit, range), true);
                            range.Text = "";
                        }
                    }
                    else if (e.Command == EditingCommands.DeleteNextWord)
                    {
                        int resOffset = FindNextWhitespaceForward(edit);

                        if (resOffset != -1)
                        {
                            TextRange range = new TextRange(
                                edit.Document.ContentStart.GetPositionAtOffset(resOffset),
                                edit.Document.ContentStart.GetPositionAtOffset(offsetFromStart));

                            PushUndoAction(new UndoBlockRemove(edit, range), true);
                            range.Text = "";
                        }
                    }
                }

                e.Handled = true;
                LinksCheck(CaretPosition);
            }

            if (e.Command == ApplicationCommands.Cut)
            {
                if (!edit.Selection.IsEmpty)
                {
                    edit.Copy();
                    RemoveSelection(this);
                    LinksCheck(CaretPosition);
                }

                e.Handled = true;
                return;
            }

            if (e.Command == ApplicationCommands.Paste)
            {
                if (!Clipboard.ContainsData(DataFormats.Rtf) && !Clipboard.ContainsData(DataFormats.Text))
                {
                    e.Handled = true;
                    return;
                }

                var undoGroup = new UndoGroup();

                // Удалить старое содержимое
                if (!edit.Selection.IsEmpty)
                {
                    FormatUndo undoFormat = new FormatUndo(edit.Document, edit.Selection, edit);
                    undoGroup.Add(undoFormat);
                    edit.Selection.Text = "";
                    undoFormat.UpdateSelectionOffsets(edit, edit.Selection);
                }

                int offsetStart = edit.Document.ContentStart.GetOffsetToPosition(edit.Selection.Start);
                int offsetEnd = edit.Document.ContentEnd.GetOffsetToPosition(edit.Selection.End);
                var undoPaste = new UndoPaste(edit, offsetStart, offsetEnd);

                bool wasError = false;
                if (Clipboard.ContainsData(DataFormats.Rtf))
                {
                    try
                    {
                        var rtfStream = MemoryStreamFromClipboard();
                        edit.Selection.Load(rtfStream, DataFormats.Rtf);
                    }
                    catch
                    {
                        wasError = true;
                    }
                }
                else if (Clipboard.ContainsData(DataFormats.Text))
                {
                    edit.Selection.Text = (string)Clipboard.GetData(DataFormats.Text);
                }

                // Если была ошибка добавления текста, то
                if (wasError == false)
                {
                    undoGroup.Add(undoPaste);
                    PushUndoAction(undoGroup, true);
                    edit.CaretPosition = edit.Selection.End;
                }

                // Проверить, все ли линки на месте
                LinksCheck(CaretPosition);

                // Обновить хендлеры у новых ссылок (которые могли прийти с клипбоардом)
                Links_Update();

                e.Handled = true;
                return;
            }

            if (e.Command == EditingCommands.AlignCenter ||
                e.Command == EditingCommands.AlignJustify ||
                e.Command == EditingCommands.AlignLeft ||
                e.Command == EditingCommands.AlignRight ||
                e.Command == EditingCommands.IncreaseIndentation ||
                e.Command == EditingCommands.TabBackward ||
                e.Command == EditingCommands.TabForward ||
                e.Command == EditingCommands.ToggleNumbering ||
                e.Command == EditingCommands.ToggleSubscript ||
                e.Command == EditingCommands.ToggleSuperscript)
            {
                e.Handled = true;
                return;
            }
            //e.Command == EditingCommands.ToggleUnderline

            if (e.Command == EditingCommands.IncreaseFontSize ||
                e.Command == EditingCommands.DecreaseFontSize ||
                e.Command == EditingCommands.ToggleBold ||
                e.Command == EditingCommands.ToggleItalic ||
                e.Command == EditingCommands.ToggleUnderline ||
                e.Command == OutlinerCommands.ToggleCrossed)
            {
                if (!edit.Selection.IsEmpty)
                {
                    var bu = new FormatUndo(edit.Document, edit.Selection, edit);
                    PushUndoAction(bu, true);

                    if (e.Command == EditingCommands.ToggleBold)
                        IsSelectionBold = !IsSelectionBold;
                    else if (e.Command == EditingCommands.ToggleItalic)
                        IsSelectionItalic = !IsSelectionItalic;
                    else if (e.Command == EditingCommands.ToggleUnderline)
                        IsSelectionUnderlined = !IsSelectionUnderlined;
                    else if (e.Command == OutlinerCommands.ToggleCrossed)
                        IsSelectionStrikethrough = !IsSelectionStrikethrough;
                    /*if (e.Command == OutlinerCommands.ToggleCrossed)
                        IsSelectionStrikethrough = !IsSelectionStrikethrough;*/

                    bu.UpdateSelectionOffsets(edit, edit.Selection);
                    e.Handled = true;
                }
                else
                {

                    TextRange paragraphRange;
                    if (edit.CaretPosition.Paragraph != null)
                        paragraphRange = new TextRange(edit.CaretPosition.Paragraph.ContentStart,
                                                             edit.CaretPosition.Paragraph.ContentEnd);
                    else
                        paragraphRange = new TextRange(edit.Document.ContentStart,
                                                             edit.Document.ContentEnd);

                    FontProperties fontProps = new FontProperties(paragraphRange);
                    var bu = new FormatUndo(edit.Document,
                                    paragraphRange,
                                    edit);

                    int caretPositionStart = edit.Document.ContentStart.GetOffsetToPosition(edit.CaretPosition);
                    int caretPositionEnd = edit.Document.ContentEnd.GetOffsetToPosition(edit.CaretPosition);

                    if (e.Command == EditingCommands.ToggleBold)
                        IsSelectionBold = !IsSelectionBold;
                    else if (e.Command == EditingCommands.ToggleItalic)
                        IsSelectionItalic = !IsSelectionItalic;
                    else if (e.Command == EditingCommands.ToggleUnderline)
                        IsSelectionUnderlined = !IsSelectionUnderlined;
                    else if (e.Command == OutlinerCommands.ToggleCrossed)
                        IsSelectionStrikethrough = !IsSelectionStrikethrough;

                    int newCaretPositionStart = edit.Document.ContentStart.GetOffsetToPosition(edit.CaretPosition);
                    int newCaretPositionEnd = edit.Document.ContentEnd.GetOffsetToPosition(edit.CaretPosition);

                    string paragraphRangeText = paragraphRange.Text;
                    if (caretPositionStart != newCaretPositionStart || caretPositionEnd != newCaretPositionEnd ||
                        !fontProps.HasSameStyle(paragraphRange))
                        PushUndoAction(bu, true);

                    e.Handled = true;
                }
                return;
            }

            if (e.Command == EditingCommands.Backspace ||
                e.Command == EditingCommands.Delete)
            {

                if (!edit.Selection.IsEmpty)
                {
                    RemoveSelection(edit);
                    LinksCheck(CaretPosition);
                    e.Handled = true;
                }
                else
                {
                    TextPointer right = edit.Selection.Start;
                    TextPointer left = right.GetNextInsertionPosition(LogicalDirection.Backward);

                    if (e.Command == EditingCommands.Delete)
                    {
                        left = edit.Selection.Start;
                        right = right.GetNextInsertionPosition(LogicalDirection.Forward);
                    }

                    if (right != null && left != null)
                    {

                        TextRange range = new TextRange(right, left);
                        if (range.Text != "")
                        {
                            var bu = new UndoBlockRemove(edit, range);
                            PushUndoAction(bu, true);

                            range.ClearAllProperties();
                            range.Text = "";

                            bu.UpdateOffsets(edit, range);
                        }
                    }

                    LinksCheck(CaretPosition);
                    e.Handled = true;
                }
            }
        }
Пример #2
0
        public void ApplyUndoAwarePropertyValue(TextRange range, DependencyProperty property, object value)
        {
            if (!range.IsEmpty)
            {
                var bu = new FormatUndo(Document, range, this);
                PushUndoAction(bu, true);

                range.ApplyPropertyValue(property, value);

                bu.UpdateSelectionOffsets(this, range);
            }
            else
            {
                TextRange paragraphRange;

                if (CaretPosition.Paragraph != null)
                    paragraphRange = new TextRange(CaretPosition.Paragraph.ContentStart,
                                                         CaretPosition.Paragraph.ContentEnd);
                else
                    paragraphRange = new TextRange(CaretPosition.DocumentStart,
                                                         CaretPosition.DocumentEnd);

                FontProperties fontProps = new FontProperties(paragraphRange);
                var bu = new FormatUndo(Document,
                                paragraphRange,
                                this);

                int caretPositionStart = Document.ContentStart.GetOffsetToPosition(CaretPosition);
                int caretPositionEnd = Document.ContentEnd.GetOffsetToPosition(CaretPosition);

                range.ApplyPropertyValue(property, value);

                int newCaretPositionStart = Document.ContentStart.GetOffsetToPosition(CaretPosition);
                int newCaretPositionEnd = Document.ContentEnd.GetOffsetToPosition(CaretPosition);

                string paragraphRangeText = paragraphRange.Text;
                if (caretPositionStart != newCaretPositionStart || caretPositionEnd != newCaretPositionEnd ||
                    !fontProps.HasSameStyle(paragraphRange))
                    PushUndoAction(bu, true);

            }
            return;
        }