| 0: | // Edit.cs | |
| 1: | // Copyright (C) 2000 Mike Krueger | |
| 2: | // | |
| 3: | // This program is free software; you can redistribute it and/or modify | |
| 4: | // it under the terms of the GNU General Public License as published by | |
| 5: | // the Free Software Foundation; either version 2 of the License, or | |
| 6: | // (at your option) any later version. | |
| 7: | // | |
| 8: | // This program is distributed in the hope that it will be useful, | |
| 9: | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10: | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 11: | // GNU General Public License for more details. | |
| 12: | // | |
| 13: | // You should have received a copy of the GNU General Public License | |
| 14: | // along with this program; if not, write to the Free Software | |
| 15: | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 16: | ||
| 17: | using Microsoft.Win32; | |
| 18: | using System; | |
| 19: | using System.Collections; | |
| 20: | using System.IO; | |
| 21: | using System.ComponentModel; | |
| 22: | using System.Windows.Forms; | |
| 23: | using System.Drawing; | |
| 24: | using System.Diagnostics; | |
| 25: | using System.CodeDom.Compiler; | |
| 26: | using System.Xml; | |
| 27: | using System.Reflection; | |
| 28: | using System.Text; | |
| 29: | ||
| 30: | using SharpDevelop.Actions; | |
| 31: | using SharpDevelop.Gui; | |
| 32: | using SharpDevelop.Gui.Edit.Text; | |
| 33: | using SharpDevelop.Gui.Dialogs; | |
| 34: | using SharpDevelop.Gui.Window; | |
| 35: | using SharpDevelop.Tool.Data; | |
| 36: | using SharpDevelop.Internal.Project; | |
| 37: | using SharpDevelop.Internal.Messages; | |
| 38: | using SharpDevelop.Internal.Text; | |
| 39: | ||
| 40: | namespace SharpDevelop.Actions.Menu { | |
| 41: | ||
| 42: | public class UndoAction : ISdPlugin | |
| 43: | { | |
| 44: | public ISdMessageHandler MessageHandler { | |
| 45: | get { | |
| 46: | return null; | |
| 47: | } | |
| 48: | } | |
| 49: | public void Execute(ISdPluginExecutor executor) | |
| 50: | { | |
| 51: | ContentWindow window = executor.Main.ActiveContentWindow; | |
| 52: | if (window != null && window.ISdEditable != null && window.ISdEditable.UndoStack != null) { | |
| 53: | if (window.HasTextArea) | |
| 54: | window.TextArea.Buffer.BeginUpdate(); | |
| 55: | window.ISdEditable.UndoStack.Undo(); | |
| 56: | if (window.HasTextArea) { | |
| 57: | window.TextArea.Caret.CheckCaretPos(); | |
| 58: | window.TextArea.Buffer.EndUpdate(); | |
| 59: | } | |
| 60: | ||
| 61: | } | |
| 62: | } | |
| 63: | } | |
| 64: | ||
| 65: | public class RedoAction : ISdPlugin | |
| 66: | { | |
| 67: | public ISdMessageHandler MessageHandler { | |
| 68: | get { | |
| 69: | return null; | |
| 70: | } | |
| 71: | } | |
| 72: | public void Execute(ISdPluginExecutor executor) | |
| 73: | { | |
| 74: | ContentWindow window = executor.Main.ActiveContentWindow; | |
| 75: | if (window != null && window.ISdEditable != null && window.ISdEditable.UndoStack != null) { | |
| 76: | if (window.HasTextArea) | |
| 77: | window.TextArea.Buffer.BeginUpdate(); | |
| 78: | window.ISdEditable.UndoStack.Redo(); | |
| 79: | if (window.HasTextArea) { | |
| 80: | window.TextArea.Caret.CheckCaretPos(); | |
| 81: | window.TextArea.Buffer.EndUpdate(); | |
| 82: | } | |
| 83: | } | |
| 84: | } | |
| 85: | } | |
| 86: | ||
| 87: | public class CutAction : ISdPlugin | |
| 88: | { | |
| 89: | public ISdMessageHandler MessageHandler { | |
| 90: | get { | |
| 91: | return null; | |
| 92: | } | |
| 93: | } | |
| 94: | public void Execute(ISdPluginExecutor executor) | |
| 95: | { | |
| 96: | ContentWindow window = executor.Main.ActiveContentWindow; | |
| 97: | if (window != null && window.ISdEditable != null) | |
| 98: | window.ISdEditable.ClipboardHandler.Cut(null, null); | |
| 99: | } | |
| 100: | } | |
| 101: | ||
| 102: | public class CopyAction : ISdPlugin | |
| 103: | { | |
| 104: | public ISdMessageHandler MessageHandler { | |
| 105: | get { | |
| 106: | return null; | |
| 107: | } | |
| 108: | } | |
| 109: | public void Execute(ISdPluginExecutor executor) | |
| 110: | { | |
| 111: | ContentWindow window = executor.Main.ActiveContentWindow; | |
| 112: | if (window != null && window.ISdEditable != null) | |
| 113: | window.ISdEditable.ClipboardHandler.Copy(null, null); | |
| 114: | } | |
| 115: | } | |
| 116: | ||
| 117: | public class PasteAction : ISdPlugin | |
| 118: | { | |
| 119: | public ISdMessageHandler MessageHandler { | |
| 120: | get { | |
| 121: | return null; | |
| 122: | } | |
| 123: | } | |
| 124: | public void Execute(ISdPluginExecutor executor) | |
| 125: | { | |
| 126: | ContentWindow window = executor.Main.ActiveContentWindow; | |
| 127: | if (window != null && window.ISdEditable != null) | |
| 128: | window.ISdEditable.ClipboardHandler.Paste(null, null); | |
| 129: | } | |
| 130: | } | |
| 131: | ||
| 132: | public class DeleteAction : ISdPlugin | |
| 133: | { | |
| 134: | public ISdMessageHandler MessageHandler { | |
| 135: | get { | |
| 136: | return null; | |
| 137: | } | |
| 138: | } | |
| 139: | public void Execute(ISdPluginExecutor executor) | |
| 140: | { | |
| 141: | ContentWindow window = executor.Main.ActiveContentWindow; | |
| 142: | if (window != null && window.ISdEditable != null) | |
| 143: | window.ISdEditable.ClipboardHandler.Delete(null, null); | |
| 144: | } | |
| 145: | } | |
| 146: | ||
| 147: | public class SelectAllAction : ISdPlugin | |
| 148: | { | |
| 149: | public ISdMessageHandler MessageHandler { | |
| 150: | get { | |
| 151: | return null; | |
| 152: | } | |
| 153: | } | |
| 154: | public void Execute(ISdPluginExecutor executor) | |
| 155: | { | |
| 156: | ContentWindow window = executor.Main.ActiveContentWindow; | |
| 157: | if (window != null && window.ISdEditable != null) | |
| 158: | window.ISdEditable.ClipboardHandler.SelectAll(null, null); | |
| 159: | } | |
| 160: | } | |
| 161: | ||
| 162: | public class WordCount : ISdPlugin | |
| 163: | { | |
| 164: | public ISdMessageHandler MessageHandler { | |
| 165: | get { | |
| 166: | return null; | |
| 167: | } | |
| 168: | } | |
| 169: | public void Execute(ISdPluginExecutor executor) | |
| 170: | { | |
| 171: | WordCountDialog wcd = new WordCountDialog(executor.Main); | |
| 172: | wcd.Owner = executor.Main; | |
| 173: | wcd.ShowDialog(); | |
| 174: | wcd.Dispose(); | |
| 175: | } | |
| 176: | } | |
| 177: | ||
| 178: | ////////////// Format sub menu | |
| 179: | ||
| 180: | public class RemoveLeadingWS : ISdPlugin | |
| 181: | { | |
| 182: | public ISdMessageHandler MessageHandler { | |
| 183: | get { | |
| 184: | return null; | |
| 185: | } | |
| 186: | } | |
| 187: | void Convert(TextAreaControl textarea, int y1, int y2) | |
| 188: | { | |
| 189: | int redocounter = 0; // must count how many Delete operations occur | |
| 190: | Point p1 = new Point(); | |
| 191: | Point p2 = new Point(); | |
| 192: | for (int i = y1; i < y2; ++i) { | |
| 193: | p1.Y = p2.Y = i; | |
| 194: | for (int x = 0; x < textarea.Buffer[i].Text.Length && Char.IsWhiteSpace(textarea.Buffer[i].Text[x]); ++x) { | |
| 195: | p1.X = x; | |
| 196: | p2.X = x + 1; | |
| 197: | textarea.Buffer.Delete(p1, p2); | |
| 198: | ++redocounter; // count deletes | |
| 199: | --x; // length changed | |
| 200: | } | |
| 201: | } | |
| 202: | textarea.Caret.CheckCaretPos(); // current cursor position may be invalid | |
| 203: | textarea.Buffer.UndoStack.UndoLast(redocounter); // redo the whole operation (not the single deletes) | |
| 204: | textarea.UpdateLines(y1, y2); | |
| 205: | } | |
| 206: | ||
| 207: | public void Execute(ISdPluginExecutor executor) | |
| 208: | { | |
| 209: | if (executor.Main.ActiveContentWindow == null || !executor.Main.ActiveContentWindow.HasTextArea) | |
| 210: | return; | |
| 211: | ||
| 212: | TextAreaControl textarea = executor.Main.ActiveContentWindow.TextArea; | |
| 213: | textarea.Buffer.BeginUpdate(); | |
| 214: | if (textarea.Selection.HasSomethingSelected) { | |
| 215: | int y = textarea.Selection.RealEnd.Y + 1; | |
| 216: | if (textarea.Selection.RealEnd.X == 0) | |
| 217: | --y; | |
| 218: | Convert(textarea, textarea.Selection.RealStart.Y, y); | |
| 219: | } else | |
| 220: | Convert(textarea, 0, textarea.Buffer.Length); | |
| 221: | textarea.Buffer.EndUpdate(); | |
| 222: | } | |
| 223: | } | |
| 224: | ||
| 225: | public class RemoveTrailingWS : ISdPlugin | |
| 226: | { | |
| 227: | public ISdMessageHandler MessageHandler { | |
| 228: | get { | |
| 229: | return null; | |
| 230: | } | |
| 231: | } | |
| 232: | void Convert(TextAreaControl textarea, int y1, int y2) | |
| 233: | { | |
| 234: | int redocounter = 0; // must count how many Delete operations occur | |
| 235: | Point p1 = new Point(); | |
| 236: | Point p2 = new Point(); | |
| 237: | for (int i = y1; i < y2; ++i) { | |
| 238: | int x = textarea.Buffer[i].Text.Length - 1; | |
| 239: | p1.Y = p2.Y = i; | |
| 240: | while (x >= 0 && Char.IsWhiteSpace(textarea.Buffer[i].Text[x])) { | |
| 241: | p1.X = x; | |
| 242: | p2.X = x + 1; | |
| 243: | textarea.Buffer.Delete(p1, p2); | |
| 244: | ++redocounter; // count deletes | |
| 245: | --x; // length changed | |
| 246: | } | |
| 247: | } | |
| 248: | textarea.Caret.CheckCaretPos(); // current cursor position may be invalid | |
| 249: | textarea.Buffer.UndoStack.UndoLast(redocounter); // redo the whole operation (not the single deletes) | |
| 250: | textarea.UpdateLines(y1, y2); | |
| 251: | } | |
| 252: | public void Execute(ISdPluginExecutor executor) | |
| 253: | { | |
| 254: | if (executor.Main.ActiveContentWindow == null || !executor.Main.ActiveContentWindow.HasTextArea) | |
| 255: | return; | |
| 256: | ||
| 257: | TextAreaControl textarea = executor.Main.ActiveContentWindow.TextArea; | |
| 258: | textarea.Buffer.BeginUpdate(); | |
| 259: | if (textarea.Selection.HasSomethingSelected) { | |
| 260: | int y = textarea.Selection.RealEnd.Y + 1; | |
| 261: | if (textarea.Selection.RealEnd.X == 0) | |
| 262: | --y; | |
| 263: | Convert(textarea, textarea.Selection.RealStart.Y, y); | |
| 264: | } else | |
| 265: | Convert(textarea, 0, textarea.Buffer.Length); | |
| 266: | textarea.Buffer.EndUpdate(); | |
| 267: | } | |
| 268: | } | |
| 269: | ||
| 270: | ||
| 271: | public class ToUpperCase : ISdPlugin | |
| 272: | { | |
| 273: | public ISdMessageHandler MessageHandler { | |
| 274: | get { | |
| 275: | return null; | |
| 276: | } | |
| 277: | } | |
| 278: | void Convert(TextAreaControl textarea, Point from, Point to) | |
| 279: | { | |
| 280: | string what = textarea.Buffer.Delete(from, to).ToUpper(); | |
| 281: | textarea.Buffer.Insert(from, what); | |
| 282: | textarea.UndoStack.UndoLast(2); | |
| 283: | textarea.UpdateLines(from.Y, to.Y); | |
| 284: | } | |
| 285: | ||
| 286: | public void Execute(ISdPluginExecutor executor) | |
| 287: | { | |
| 288: | ContentWindow window = executor.Main.ActiveContentWindow; | |
| 289: | if (window != null && window.HasTextArea) { | |
| 290: | TextAreaControl textarea = window.TextArea; | |
| 291: | ||
| 292: | textarea.Buffer.BeginUpdate(); | |
| 293: | if (textarea.Selection.HasSomethingSelected) { | |
| 294: | Convert(textarea, textarea.Selection.RealStart, textarea.Selection.RealEnd); | |
| 295: | } else | |
| 296: | if (textarea.Caret.CaretPos.X < textarea.Buffer[textarea.Caret.CaretPos.Y].Text.Length) // cursor at line end ? | |
| 297: | Convert(textarea, textarea.Caret.CaretPos, new Point(textarea.Caret.CaretPos.X + 1, textarea.Caret.CaretPos.Y)); | |
| 298: | textarea.Buffer.EndUpdate(); | |
| 299: | } | |
| 300: | } | |
| 301: | } | |
| 302: | public class ToLowerCase : ISdPlugin | |
| 303: | { | |
| 304: | public ISdMessageHandler MessageHandler { | |
| 305: | get { | |
| 306: | return null; | |
| 307: | } | |
| 308: | } | |
| 309: | void Convert(TextAreaControl textarea, Point from, Point to) | |
| 310: | { | |
| 311: | string what = textarea.Buffer.Delete(from, to).ToLower(); | |
| 312: | textarea.Buffer.Insert(from, what); | |
| 313: | textarea.UndoStack.UndoLast(2); | |
| 314: | textarea.UpdateLines(from.Y, to.Y); | |
| 315: | } | |
| 316: | ||
| 317: | public void Execute(ISdPluginExecutor executor) | |
| 318: | { | |
| 319: | ContentWindow window = executor.Main.ActiveContentWindow; | |
| 320: | if (window != null && window.HasTextArea) { | |
| 321: | TextAreaControl textarea = window.TextArea; | |
| 322: | ||
| 323: | if (textarea.Selection.HasSomethingSelected) { | |
| 324: | Convert(textarea, textarea.Selection.RealStart, textarea.Selection.RealEnd); | |
| 325: | } else | |
| 326: | if (textarea.Caret.CaretPos.X < textarea.Buffer[textarea.Caret.CaretPos.Y].Text.Length) // cursor at line end ? | |
| 327: | Convert(textarea, textarea.Caret.CaretPos, new Point(textarea.Caret.CaretPos.X + 1, textarea.Caret.CaretPos.Y)); | |
| 328: | } | |
| 329: | } | |
| 330: | } | |
| 331: | public class InvertCaseAction : ISdPlugin | |
| 332: | { | |
| 333: | public ISdMessageHandler MessageHandler { | |
| 334: | get { | |
| 335: | return null; | |
| 336: | } | |
| 337: | } | |
| 338: | void Convert(TextAreaControl textarea, Point from, Point to) | |
| 339: | { | |
| 340: | StringBuilder what = new StringBuilder(textarea.Buffer.Delete(from, to)); | |
| 341: | for (int i = 0; i < what.Length; ++i) { | |
| 342: | if (Char.IsUpper(what[i])) | |
| 343: | what[i] = Char.ToLower(what[i]); | |
| 344: | else | |
| 345: | what[i] = Char.ToUpper(what[i]); | |
| 346: | } | |
| 347: | textarea.Buffer.Insert(from, what.ToString()); | |
| 348: | textarea.UndoStack.UndoLast(2); | |
| 349: | textarea.UpdateLines(from.Y, to.Y); | |
| 350: | } | |
| 351: | ||
| 352: | public void Execute(ISdPluginExecutor executor) | <