TextBoxBase.cs 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:c
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2004-2006 Novell, Inc. (http://www.novell.com)
  21. //
  22. // Authors:
  23. // Peter Bartok [email protected]
  24. //
  25. //
  26. // NOT COMPLETE
  27. #undef Debug
  28. #undef DebugClick
  29. using System.ComponentModel;
  30. using System.ComponentModel.Design;
  31. using System.Drawing;
  32. using System.Drawing.Text;
  33. using System.Text;
  34. using System.Runtime.InteropServices;
  35. using System.Collections;
  36. namespace System.Windows.Forms {
  37. [DefaultEvent("TextChanged")]
  38. [Designer("System.Windows.Forms.Design.TextBoxBaseDesigner, " + Consts.AssemblySystem_Design)]
  39. public abstract class TextBoxBase : Control {
  40. #region Local Variables
  41. internal HorizontalAlignment alignment;
  42. internal bool accepts_tab;
  43. internal bool accepts_return;
  44. internal bool auto_size;
  45. internal bool backcolor_set;
  46. internal CharacterCasing character_casing;
  47. internal bool hide_selection;
  48. internal int max_length;
  49. internal bool modified;
  50. internal char password_char;
  51. internal bool read_only;
  52. internal bool word_wrap;
  53. internal Document document;
  54. internal LineTag caret_tag; // tag our cursor is in
  55. internal int caret_pos; // position on the line our cursor is in (can be 0 = beginning of line)
  56. internal ImplicitHScrollBar hscroll;
  57. internal ImplicitVScrollBar vscroll;
  58. internal RichTextBoxScrollBars scrollbars;
  59. internal Timer scroll_timer;
  60. internal bool richtext;
  61. internal bool show_selection; // set to true to always show selection, even if no focus is set
  62. internal bool has_been_focused;
  63. internal int selection_length = -1; // set to the user-specified selection length, or -1 if none
  64. internal bool show_caret_w_selection; // TextBox shows the caret when the selection is visible
  65. internal int requested_height;
  66. internal int canvas_width;
  67. internal int canvas_height;
  68. static internal int track_width = 2; //
  69. static internal int track_border = 5; //
  70. internal DateTime click_last;
  71. internal int click_point_x;
  72. internal int click_point_y;
  73. internal CaretSelection click_mode;
  74. internal Bitmap bmp;
  75. internal BorderStyle actual_border_style;
  76. internal bool shortcuts_enabled = true;
  77. #if Debug
  78. internal static bool draw_lines = false;
  79. #endif
  80. #endregion // Local Variables
  81. #region Internal Constructor
  82. // Constructor will go when complete, only for testing - pdb
  83. internal TextBoxBase() {
  84. alignment = HorizontalAlignment.Left;
  85. accepts_return = false;
  86. accepts_tab = false;
  87. auto_size = true;
  88. InternalBorderStyle = BorderStyle.Fixed3D;
  89. actual_border_style = BorderStyle.Fixed3D;
  90. character_casing = CharacterCasing.Normal;
  91. hide_selection = true;
  92. max_length = 32767;
  93. modified = true;
  94. password_char = '\0';
  95. read_only = false;
  96. word_wrap = true;
  97. richtext = false;
  98. show_selection = false;
  99. show_caret_w_selection = (this is TextBox);
  100. document = new Document(this);
  101. document.WidthChanged += new EventHandler(document_WidthChanged);
  102. document.HeightChanged += new EventHandler(document_HeightChanged);
  103. //document.CaretMoved += new EventHandler(CaretMoved);
  104. document.Wrap = false;
  105. requested_height = -1;
  106. click_last = DateTime.Now;
  107. click_mode = CaretSelection.Position;
  108. bmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
  109. MouseDown += new MouseEventHandler(TextBoxBase_MouseDown);
  110. MouseUp += new MouseEventHandler(TextBoxBase_MouseUp);
  111. MouseMove += new MouseEventHandler(TextBoxBase_MouseMove);
  112. SizeChanged += new EventHandler(TextBoxBase_SizeChanged);
  113. FontChanged += new EventHandler(TextBoxBase_FontOrColorChanged);
  114. ForeColorChanged += new EventHandler(TextBoxBase_FontOrColorChanged);
  115. MouseWheel += new MouseEventHandler(TextBoxBase_MouseWheel);
  116. scrollbars = RichTextBoxScrollBars.None;
  117. hscroll = new ImplicitHScrollBar();
  118. hscroll.ValueChanged += new EventHandler(hscroll_ValueChanged);
  119. hscroll.SetStyle (ControlStyles.Selectable, false);
  120. hscroll.Enabled = false;
  121. hscroll.Visible = false;
  122. hscroll.Maximum = Int32.MaxValue;
  123. vscroll = new ImplicitVScrollBar();
  124. vscroll.ValueChanged += new EventHandler(vscroll_ValueChanged);
  125. vscroll.SetStyle (ControlStyles.Selectable, false);
  126. vscroll.Enabled = false;
  127. vscroll.Visible = false;
  128. vscroll.Maximum = Int32.MaxValue;
  129. SuspendLayout ();
  130. this.Controls.AddImplicit (hscroll);
  131. this.Controls.AddImplicit (vscroll);
  132. ResumeLayout ();
  133. SetStyle(ControlStyles.UserPaint | ControlStyles.StandardClick, false);
  134. #if NET_2_0
  135. SetStyle(ControlStyles.UseTextForAccessibility, false);
  136. #endif
  137. canvas_width = ClientSize.Width;
  138. canvas_height = ClientSize.Height;
  139. document.ViewPortWidth = canvas_width;
  140. document.ViewPortHeight = canvas_height;
  141. Cursor = Cursors.IBeam;
  142. }
  143. #endregion // Internal Constructor
  144. #region Private and Internal Methods
  145. internal string CaseAdjust(string s) {
  146. if (character_casing == CharacterCasing.Normal) {
  147. return s;
  148. }
  149. if (character_casing == CharacterCasing.Lower) {
  150. return s.ToLower();
  151. } else {
  152. return s.ToUpper();
  153. }
  154. }
  155. internal override void HandleClick(int clicks, MouseEventArgs me) {
  156. // MS seems to fire the click event in spite of the styles they set
  157. bool click_set = GetStyle (ControlStyles.StandardClick);
  158. bool doubleclick_set = GetStyle (ControlStyles.StandardDoubleClick);
  159. // so explicitly set them to true first
  160. SetStyle (ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, true);
  161. base.HandleClick (clicks, me);
  162. // then revert to our previous state
  163. if (!click_set)
  164. SetStyle (ControlStyles.StandardClick, false);
  165. if (!doubleclick_set)
  166. SetStyle (ControlStyles.StandardDoubleClick, false);
  167. }
  168. #endregion // Private and Internal Methods
  169. #region Public Instance Properties
  170. [DefaultValue(false)]
  171. [MWFCategory("Behavior")]
  172. public bool AcceptsTab {
  173. get {
  174. return accepts_tab;
  175. }
  176. set {
  177. if (value != accepts_tab) {
  178. accepts_tab = value;
  179. OnAcceptsTabChanged(EventArgs.Empty);
  180. }
  181. }
  182. }
  183. [DefaultValue(true)]
  184. [Localizable(true)]
  185. [RefreshProperties(RefreshProperties.Repaint)]
  186. [MWFCategory("Behavior")]
  187. public
  188. #if NET_2_0
  189. override
  190. #else
  191. virtual
  192. #endif
  193. bool AutoSize {
  194. get {
  195. return auto_size;
  196. }
  197. set {
  198. if (value != auto_size) {
  199. auto_size = value;
  200. if (auto_size) {
  201. if (PreferredHeight != ClientSize.Height) {
  202. ClientSize = new Size(ClientSize.Width, PreferredHeight);
  203. }
  204. }
  205. #if NET_1_1
  206. OnAutoSizeChanged(EventArgs.Empty);
  207. #endif
  208. }
  209. }
  210. }
  211. [DispId(-501)]
  212. public override System.Drawing.Color BackColor {
  213. get {
  214. return base.BackColor;
  215. }
  216. set {
  217. backcolor_set = true;
  218. base.BackColor = ChangeBackColor (value);
  219. }
  220. }
  221. [Browsable(false)]
  222. [EditorBrowsable(EditorBrowsableState.Never)]
  223. public override System.Drawing.Image BackgroundImage {
  224. get {
  225. return base.BackgroundImage;
  226. }
  227. set {
  228. base.BackgroundImage = value;
  229. }
  230. }
  231. [DefaultValue(BorderStyle.Fixed3D)]
  232. [DispId(-504)]
  233. [MWFCategory("Appearance")]
  234. public BorderStyle BorderStyle {
  235. get { return actual_border_style; }
  236. set {
  237. if (value == actual_border_style)
  238. return;
  239. if (actual_border_style != BorderStyle.Fixed3D || value != BorderStyle.Fixed3D)
  240. Invalidate ();
  241. actual_border_style = value;
  242. document.UpdateMargins ();
  243. if (value != BorderStyle.Fixed3D)
  244. value = BorderStyle.None;
  245. InternalBorderStyle = value;
  246. OnBorderStyleChanged(EventArgs.Empty);
  247. }
  248. }
  249. [Browsable(false)]
  250. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  251. public bool CanUndo {
  252. get {
  253. return document.undo.CanUndo;
  254. }
  255. }
  256. [DispId(-513)]
  257. public override System.Drawing.Color ForeColor {
  258. get {
  259. return base.ForeColor;
  260. }
  261. set {
  262. base.ForeColor = value;
  263. }
  264. }
  265. [DefaultValue(true)]
  266. [MWFCategory("Behavior")]
  267. public bool HideSelection {
  268. get {
  269. return hide_selection;
  270. }
  271. set {
  272. if (value != hide_selection) {
  273. hide_selection = value;
  274. OnHideSelectionChanged(EventArgs.Empty);
  275. }
  276. if (hide_selection) {
  277. document.selection_visible = false;
  278. } else {
  279. document.selection_visible = true;
  280. }
  281. document.InvalidateSelectionArea();
  282. }
  283. }
  284. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  285. [Editor("System.Windows.Forms.Design.StringArrayEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
  286. [Localizable(true)]
  287. [MWFCategory("Appearance")]
  288. public string[] Lines {
  289. get {
  290. int count;
  291. ArrayList lines;
  292. count = document.Lines;
  293. // Handle empty document
  294. if ((count == 1) && (document.GetLine (1).text.Length == 0)) {
  295. return new string [0];
  296. }
  297. lines = new ArrayList ();
  298. int i = 1;
  299. while (i <= count) {
  300. Line line;
  301. StringBuilder lt = new StringBuilder ();
  302. do {
  303. line = document.GetLine (i++);
  304. lt.Append (line.TextWithoutEnding ());
  305. } while (line.ending == LineEnding.Wrap && i <= count);
  306. lines.Add (lt.ToString ());
  307. }
  308. return (string []) lines.ToArray (typeof (string));
  309. }
  310. set {
  311. int i;
  312. int l;
  313. SolidBrush brush;
  314. document.Empty();
  315. l = value.Length;
  316. brush = ThemeEngine.Current.ResPool.GetSolidBrush(this.ForeColor);
  317. document.SuspendRecalc ();
  318. for (i = 0; i < l; i++) {
  319. // Don't add the last line if it is just an empty line feed
  320. // the line feed is reflected in the previous line's ending
  321. if (i == l - 1 && value [i].Length == 0)
  322. break;
  323. LineEnding ending = LineEnding.Rich;
  324. if (value [i].EndsWith ("\r"))
  325. ending = LineEnding.Hard;
  326. document.Add (i + 1, CaseAdjust (value [i]), alignment, Font, brush, ending);
  327. }
  328. document.ResumeRecalc (true);
  329. // CalculateDocument();
  330. OnTextChanged(EventArgs.Empty);
  331. }
  332. }
  333. [DefaultValue(32767)]
  334. [Localizable(true)]
  335. [MWFCategory("Behavior")]
  336. public virtual int MaxLength {
  337. get {
  338. if (max_length == 2147483646) { // We don't distinguish between single and multi-line limits
  339. return 0;
  340. }
  341. return max_length;
  342. }
  343. set {
  344. if (value != max_length) {
  345. max_length = value;
  346. }
  347. }
  348. }
  349. [Browsable(false)]
  350. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  351. public bool Modified {
  352. get {
  353. return modified;
  354. }
  355. set {
  356. if (value != modified) {
  357. modified = value;
  358. OnModifiedChanged(EventArgs.Empty);
  359. }
  360. }
  361. }
  362. [DefaultValue(false)]
  363. [Localizable(true)]
  364. [RefreshProperties(RefreshProperties.All)]
  365. [MWFCategory("Behavior")]
  366. public virtual bool Multiline {
  367. get {
  368. return document.multiline;
  369. }
  370. set {
  371. if (value != document.multiline) {
  372. document.multiline = value;
  373. // Make sure we update our size; the user may have already set the size before going to multiline
  374. if (document.multiline && requested_height != -1) {
  375. Height = requested_height;
  376. requested_height = -1;
  377. }
  378. if (Parent != null)
  379. Parent.PerformLayout ();
  380. OnMultilineChanged(EventArgs.Empty);
  381. }
  382. if (document.multiline) {
  383. document.Wrap = word_wrap;
  384. document.PasswordChar = "";
  385. } else {
  386. document.Wrap = false;
  387. if (this.password_char != '\0') {
  388. document.PasswordChar = password_char.ToString();
  389. } else {
  390. document.PasswordChar = "";
  391. }
  392. }
  393. if (IsHandleCreated)
  394. CalculateDocument ();
  395. }
  396. }
  397. [Browsable(false)]
  398. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  399. [EditorBrowsable(EditorBrowsableState.Advanced)]
  400. public int PreferredHeight {
  401. get {
  402. return Font.Height + (BorderStyle == BorderStyle.None ? 1 : 8);
  403. }
  404. }
  405. [DefaultValue(false)]
  406. [MWFCategory("Behavior")]
  407. public bool ReadOnly {
  408. get {
  409. return read_only;
  410. }
  411. set {
  412. if (value != read_only) {
  413. read_only = value;
  414. #if NET_2_0
  415. if (!backcolor_set) {
  416. if (read_only)
  417. background_color = SystemColors.Control;
  418. else
  419. background_color = SystemColors.Window;
  420. }
  421. #endif
  422. OnReadOnlyChanged(EventArgs.Empty);
  423. Invalidate ();
  424. }
  425. }
  426. }
  427. [Browsable(false)]
  428. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  429. public virtual string SelectedText {
  430. get {
  431. return document.GetSelection();
  432. }
  433. set {
  434. document.ReplaceSelection(CaseAdjust(value), false);
  435. ScrollToCaret();
  436. OnTextChanged(EventArgs.Empty);
  437. }
  438. }
  439. [Browsable(false)]
  440. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  441. public virtual int SelectionLength {
  442. get {
  443. int res = document.SelectionLength ();
  444. if (res == 0)
  445. res = -1;
  446. return res;
  447. }
  448. set {
  449. if (value < 0) {
  450. throw new ArgumentException(String.Format("{0} is not a valid value", value), "value");
  451. }
  452. if (value != 0) {
  453. int start;
  454. Line line;
  455. LineTag tag;
  456. int pos;
  457. selection_length = value;
  458. start = document.LineTagToCharIndex(document.selection_start.line, document.selection_start.pos);
  459. document.CharIndexToLineTag(start + value, out line, out tag, out pos);
  460. document.SetSelectionEnd(line, pos, true);
  461. document.PositionCaret(line, pos);
  462. } else {
  463. selection_length = -1;
  464. document.SetSelectionEnd(document.selection_start.line, document.selection_start.pos, true);
  465. document.PositionCaret(document.selection_start.line, document.selection_start.pos);
  466. }
  467. }
  468. }
  469. [Browsable(false)]
  470. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  471. public int SelectionStart {
  472. get {
  473. int index;
  474. index = document.LineTagToCharIndex(document.selection_start.line, document.selection_start.pos);
  475. return index;
  476. }
  477. set {
  478. document.SetSelectionStart(value, false);
  479. if (selection_length > -1 ) {
  480. document.SetSelectionEnd(value + selection_length, true);
  481. } else {
  482. document.SetSelectionEnd(value, true);
  483. }
  484. document.PositionCaret(document.selection_start.line, document.selection_start.pos);
  485. ScrollToCaret();
  486. }
  487. }
  488. #if NET_2_0
  489. public virtual bool ShortcutsEnabled {
  490. get { return shortcuts_enabled; }
  491. set { shortcuts_enabled = value; }
  492. }
  493. #endif
  494. [Localizable(true)]
  495. public override string Text {
  496. get {
  497. if (document == null || document.Root == null || document.Root.text == null) {
  498. return string.Empty;
  499. }
  500. StringBuilder sb = new StringBuilder();
  501. Line line = null;
  502. for (int i = 1; i <= document.Lines; i++) {
  503. line = document.GetLine (i);
  504. sb.Append(line.text.ToString ());
  505. }
  506. return sb.ToString();
  507. }
  508. set {
  509. // reset to force a select all next time the box gets focus
  510. has_been_focused = false;
  511. if (value == Text)
  512. return;
  513. if ((value != null) && (value != "")) {
  514. document.Empty ();
  515. document.Insert (document.GetLine (1), 0, false, value);
  516. document.PositionCaret (document.GetLine (1), 0);
  517. document.SetSelectionToCaret (true);
  518. ScrollToCaret ();
  519. } else {
  520. document.Empty();
  521. if (IsHandleCreated)
  522. CalculateDocument ();
  523. }
  524. // set the var so OnModifiedChanged is not raised
  525. modified = false;
  526. OnTextChanged(EventArgs.Empty);
  527. }
  528. }
  529. [Browsable(false)]
  530. public virtual int TextLength {
  531. get {
  532. if (document == null || document.Root == null || document.Root.text == null) {
  533. return 0;
  534. }
  535. return Text.Length;
  536. }
  537. }
  538. [DefaultValue(true)]
  539. [Localizable(true)]
  540. [MWFCategory("Behavior")]
  541. public bool WordWrap {
  542. get {
  543. return word_wrap;
  544. }
  545. set {
  546. if (value != word_wrap) {
  547. if (document.multiline) {
  548. word_wrap = value;
  549. document.Wrap = value;
  550. }
  551. CalculateDocument ();
  552. }
  553. }
  554. }
  555. #if NET_2_0
  556. public override ImageLayout BackgroundImageLayout {
  557. get { return base.BackgroundImageLayout; }
  558. set { base.BackgroundImageLayout = value; }
  559. }
  560. protected override Cursor DefaultCursor {
  561. get { return Cursors.IBeam; }
  562. }
  563. #endif
  564. #endregion // Public Instance Properties
  565. #region Protected Instance Properties
  566. protected override CreateParams CreateParams {
  567. get {
  568. return base.CreateParams;
  569. }
  570. }
  571. protected override System.Drawing.Size DefaultSize {
  572. get {
  573. return new Size(100, 20);
  574. }
  575. }
  576. #if NET_2_0
  577. // Currently our double buffering breaks our scrolling, so don't let people enable this
  578. protected override bool DoubleBuffered {
  579. get { return false; }
  580. set { }
  581. }
  582. #endif
  583. #endregion // Protected Instance Properties
  584. #region Public Instance Methods
  585. public void AppendText(string text)
  586. {
  587. // Save some cycles and only check the Text if we are one line
  588. bool is_empty = document.Lines == 1 && Text == String.Empty;
  589. document.MoveCaret (CaretDirection.CtrlEnd);
  590. document.Insert (document.caret.line, document.caret.pos, false, text);
  591. document.MoveCaret (CaretDirection.CtrlEnd);
  592. document.SetSelectionToCaret (true);
  593. if (!is_empty)
  594. ScrollToCaret ();
  595. //
  596. // Avoid the initial focus selecting all when append text is used
  597. //
  598. has_been_focused = true;
  599. OnTextChanged(EventArgs.Empty);
  600. }
  601. public void Clear() {
  602. Text = null;
  603. }
  604. public void ClearUndo() {
  605. document.undo.Clear();
  606. }
  607. public void Copy() {
  608. DataObject o;
  609. o = new DataObject(DataFormats.Text, SelectedText);
  610. if (this is RichTextBox) {
  611. o.SetData(DataFormats.Rtf, ((RichTextBox)this).SelectedRtf);
  612. }
  613. Clipboard.SetDataObject(o);
  614. }
  615. public void Cut() {
  616. DataObject o;
  617. o = new DataObject(DataFormats.Text, SelectedText);
  618. if (this is RichTextBox) {
  619. o.SetData(DataFormats.Rtf, ((RichTextBox)this).SelectedRtf);
  620. }
  621. Clipboard.SetDataObject (o);
  622. document.undo.BeginUserAction (Locale.GetText ("Cut"));
  623. document.ReplaceSelection (String.Empty, false);
  624. document.undo.EndUserAction ();
  625. }
  626. public void Paste() {
  627. Paste(Clipboard.GetDataObject(), null, false);
  628. }
  629. public void ScrollToCaret() {
  630. if (IsHandleCreated) {
  631. CaretMoved(this, EventArgs.Empty);
  632. }
  633. }
  634. public void Select(int start, int length) {
  635. SelectionStart = start;
  636. SelectionLength = length;
  637. }
  638. public void SelectAll() {
  639. Line last;
  640. last = document.GetLine(document.Lines);
  641. document.SetSelectionStart(document.GetLine(1), 0, false);
  642. document.SetSelectionEnd(last, last.text.Length, true);
  643. document.PositionCaret (document.selection_end.line, document.selection_end.pos);
  644. selection_length = -1;
  645. CaretMoved (this, null);
  646. document.DisplayCaret ();
  647. }
  648. internal void SelectAllNoScroll ()
  649. {
  650. Line last;
  651. last = document.GetLine(document.Lines);
  652. document.SetSelectionStart(document.GetLine(1), 0, false);
  653. document.SetSelectionEnd(last, last.text.Length, false);
  654. document.PositionCaret (document.selection_end.line, document.selection_end.pos);
  655. selection_length = -1;
  656. document.DisplayCaret ();
  657. }
  658. public override string ToString() {
  659. return String.Concat (base.ToString (), ", Text: ", Text);
  660. }
  661. public void Undo() {
  662. document.undo.Undo();
  663. }
  664. #if NET_2_0
  665. public void DeselectAll ()
  666. {
  667. SelectionLength = 0;
  668. }
  669. public virtual char GetCharFromPosition (Point p)
  670. {
  671. int index;
  672. LineTag tag = document.FindCursor (p.X, p.Y, out index);
  673. if (tag == null)
  674. return (char) 0; // Shouldn't happen
  675. if (index >= tag.line.text.Length) {
  676. if (tag.line.ending == LineEnding.Wrap) {
  677. // If we have wrapped text, we return the first char of the next line
  678. Line line = document.GetLine (tag.line.line_no + 1);
  679. if (line != null)
  680. return line.text [0];
  681. }
  682. if (tag.line.line_no == document.Lines) {
  683. // Last line returns the last char
  684. return tag.line.text [tag.line.text.Length - 1];
  685. }
  686. // This really shouldn't happen
  687. return (char) 0;
  688. }
  689. return tag.line.text [index];
  690. }
  691. public virtual int GetCharIndexFromPosition (Point p)
  692. {
  693. int line_index;
  694. LineTag tag = document.FindCursor (p.X, p.Y, out line_index);
  695. if (tag == null)
  696. return 0;
  697. if (line_index >= tag.line.text.Length) {
  698. if (tag.line.ending == LineEnding.Wrap) {
  699. // If we have wrapped text, we return the first char of the next line
  700. Line line = document.GetLine (tag.line.line_no + 1);
  701. if (line != null)
  702. return document.LineTagToCharIndex (line, 0);
  703. }
  704. if (tag.line.line_no == document.Lines) {
  705. // Last line returns the last char
  706. return document.LineTagToCharIndex (tag.line, tag.line.text.Length - 1);
  707. }
  708. return 0;
  709. }
  710. return document.LineTagToCharIndex (tag.line, line_index);
  711. }
  712. public virtual Point GetPositionFromCharIndex (int index)
  713. {
  714. int pos;
  715. Line line;
  716. LineTag tag;
  717. document.CharIndexToLineTag (index, out line, out tag, out pos);
  718. return new Point ((int) (line.widths [pos] +
  719. line.X + document.viewport_x),
  720. line.Y + document.viewport_y + tag.shift);
  721. }
  722. public int GetFirstCharIndexFromLine (int line_number)
  723. {
  724. Line line = document.GetLine (line_number + 1);
  725. if (line == null)
  726. return -1;
  727. return document.LineTagToCharIndex (line, 0);
  728. }
  729. public int GetFirstCharIndexOfCurrentLine ()
  730. {
  731. return document.LineTagToCharIndex (document.caret.line, 0);
  732. }
  733. #endif
  734. #endregion // Public Instance Methods
  735. #region Protected Instance Methods
  736. protected override void CreateHandle() {
  737. CalculateDocument ();
  738. base.CreateHandle ();
  739. document.AlignCaret();
  740. ScrollToCaret();
  741. }
  742. protected override bool IsInputKey(Keys keyData) {
  743. if ((keyData & Keys.Alt) != 0) {
  744. return base.IsInputKey(keyData);
  745. }
  746. switch (keyData & Keys.KeyCode) {
  747. case Keys.Enter: {
  748. if (accepts_return && document.multiline) {
  749. return true;
  750. }
  751. return false;
  752. }
  753. case Keys.Tab: {
  754. if (accepts_tab && document.multiline) {
  755. if ((keyData & Keys.Control) == 0) {
  756. return true;
  757. }
  758. }
  759. return false;
  760. }
  761. case Keys.Left:
  762. case Keys.Right:
  763. case Keys.Up:
  764. case Keys.Down:
  765. case Keys.PageUp:
  766. case Keys.PageDown:
  767. case Keys.Home:
  768. case Keys.End: {
  769. return true;
  770. }
  771. }
  772. return false;
  773. }
  774. protected virtual void OnAcceptsTabChanged(EventArgs e) {
  775. EventHandler eh = (EventHandler)(Events [AcceptsTabChangedEvent]);
  776. if (eh != null)
  777. eh (this, e);
  778. }
  779. #if NET_1_1
  780. protected virtual void OnAutoSizeChanged(EventArgs e) {
  781. EventHandler eh = (EventHandler)(Events [AutoSizeChangedEvent]);
  782. if (eh != null)
  783. eh (this, e);
  784. }
  785. #endif
  786. protected virtual void OnBorderStyleChanged(EventArgs e) {
  787. EventHandler eh = (EventHandler)(Events [BorderStyleChangedEvent]);
  788. if (eh != null)
  789. eh (this, e);
  790. }
  791. protected override void OnFontChanged(EventArgs e) {
  792. base.OnFontChanged (e);
  793. if (auto_size && !document.multiline) {
  794. if (PreferredHeight != ClientSize.Height) {
  795. Height = PreferredHeight;
  796. }
  797. }
  798. }
  799. protected override void OnHandleCreated(EventArgs e) {
  800. base.OnHandleCreated (e);
  801. FixupHeight ();
  802. }
  803. protected override void OnHandleDestroyed(EventArgs e) {
  804. base.OnHandleDestroyed (e);
  805. }
  806. protected virtual void OnHideSelectionChanged(EventArgs e) {
  807. EventHandler eh = (EventHandler)(Events [HideSelectionChangedEvent]);
  808. if (eh != null)
  809. eh (this, e);
  810. }
  811. protected virtual void OnModifiedChanged(EventArgs e) {
  812. EventHandler eh = (EventHandler)(Events [ModifiedChangedEvent]);
  813. if (eh != null)
  814. eh (this, e);
  815. }
  816. protected virtual void OnMultilineChanged(EventArgs e) {
  817. EventHandler eh = (EventHandler)(Events [MultilineChangedEvent]);
  818. if (eh != null)
  819. eh (this, e);
  820. }
  821. protected virtual void OnReadOnlyChanged(EventArgs e) {
  822. EventHandler eh = (EventHandler)(Events [ReadOnlyChangedEvent]);
  823. if (eh != null)
  824. eh (this, e);
  825. }
  826. #if NET_2_0
  827. protected override bool ProcessCmdKey (ref Message msg, Keys keyData)
  828. {
  829. return base.ProcessCmdKey (ref msg, keyData);
  830. }
  831. #endif
  832. protected override bool ProcessDialogKey(Keys keyData) {
  833. return base.ProcessDialogKey(keyData);
  834. }
  835. private bool ProcessKey(Keys keyData) {
  836. bool control;
  837. bool shift;
  838. control = (Control.ModifierKeys & Keys.Control) != 0;
  839. shift = (Control.ModifierKeys & Keys.Shift) != 0;
  840. if (shortcuts_enabled) {
  841. switch (keyData & Keys.KeyCode) {
  842. case Keys.X:
  843. if (control) {
  844. Cut();
  845. return true;
  846. }
  847. return false;
  848. case Keys.C:
  849. if (control) {
  850. Copy();
  851. return true;
  852. }
  853. return false;
  854. case Keys.V:
  855. if (control) {
  856. return Paste(Clipboard.GetDataObject(), null, true);
  857. }
  858. return false;
  859. case Keys.Z:
  860. if (control) {
  861. Undo();
  862. return true;
  863. }
  864. return false;
  865. case Keys.A:
  866. if (control) {
  867. SelectAll();
  868. return true;
  869. }
  870. return false;
  871. case Keys.Insert:
  872. if (shift) {
  873. Paste(Clipboard.GetDataObject(), null, true);
  874. return true;
  875. }
  876. if (control) {
  877. Copy();
  878. return true;
  879. }
  880. return false;
  881. case Keys.Delete:
  882. if (shift) {
  883. Cut();
  884. return true;
  885. }
  886. if (read_only)
  887. break;
  888. if (document.selection_visible) {
  889. document.ReplaceSelection("", false);
  890. } else {
  891. // DeleteChar only deletes on the line, doesn't do the combine
  892. if (document.CaretPosition >= document.CaretLine.TextLengthWithoutEnding ()) {
  893. if (document.CaretLine.LineNo < document.Lines) {
  894. Line line;
  895. line = document.GetLine(document.CaretLine.LineNo + 1);
  896. // this line needs to be invalidated before it is combined
  897. // because once it is combined, all it's coordinates will
  898. // have changed
  899. document.Invalidate (line, 0, line, line.text.Length);
  900. document.Combine(document.CaretLine, line);
  901. document.UpdateView(document.CaretLine,
  902. document.Lines, 0);
  903. }
  904. } else {
  905. if (!control) {
  906. document.DeleteChar(document.CaretTag, document.CaretPosition, true);
  907. } else {
  908. int end_pos;
  909. end_pos = document.CaretPosition;
  910. while ((end_pos < document.CaretLine.Text.Length) && !Document.IsWordSeparator(document.CaretLine.Text[end_pos])) {
  911. end_pos++;
  912. }
  913. if (end_pos < document.CaretLine.Text.Length) {
  914. end_pos++;
  915. }
  916. document.DeleteChars(document.CaretTag, document.CaretPosition, end_pos - document.CaretPosition);
  917. }
  918. }
  919. }
  920. OnTextChanged(EventArgs.Empty);
  921. document.AlignCaret();
  922. document.UpdateCaret();
  923. CaretMoved(this, null);
  924. return true;
  925. }
  926. }
  927. switch (keyData & Keys.KeyCode) {
  928. case Keys.Left: {
  929. if (control) {
  930. document.MoveCaret(CaretDirection.WordBack);
  931. } else {
  932. if (!document.selection_visible || shift) {
  933. document.MoveCaret(CaretDirection.CharBack);
  934. } else {
  935. document.MoveCaret(CaretDirection.SelectionStart);
  936. }
  937. }
  938. if (!shift) {
  939. document.SetSelectionToCaret(true);
  940. } else {
  941. document.SetSelectionToCaret(false);
  942. }
  943. CaretMoved(this, null);
  944. return true;
  945. }
  946. case Keys.Right: {
  947. if (control) {
  948. document.MoveCaret(CaretDirection.WordForward);
  949. } else {
  950. if (!document.selection_visible || shift) {
  951. document.MoveCaret(CaretDirection.CharForward);
  952. } else {
  953. document.MoveCaret(CaretDirection.SelectionEnd);
  954. }
  955. }
  956. if (!shift) {
  957. document.SetSelectionToCaret(true);
  958. } else {
  959. document.SetSelectionToCaret(false);
  960. }
  961. CaretMoved(this, null);
  962. return true;
  963. }
  964. case Keys.Up: {
  965. if (control) {
  966. if (document.CaretPosition == 0) {
  967. document.MoveCaret(CaretDirection.LineUp);
  968. } else {
  969. document.MoveCaret(CaretDirection.Home);
  970. }
  971. } else {
  972. document.MoveCaret(CaretDirection.LineUp);
  973. }
  974. if ((Control.ModifierKeys & Keys.Shift) == 0) {
  975. document.SetSelectionToCaret(true);
  976. } else {
  977. document.SetSelectionToCaret(false);
  978. }
  979. CaretMoved(this, null);
  980. return true;
  981. }
  982. case Keys.Down: {
  983. if (control) {
  984. if (document.CaretPosition == document.CaretLine.Text.Length) {
  985. document.MoveCaret(CaretDirection.LineDown);
  986. } else {
  987. document.MoveCaret(CaretDirection.End);
  988. }
  989. } else {
  990. document.MoveCaret(CaretDirection.LineDown);
  991. }
  992. if ((Control.ModifierKeys & Keys.Shift) == 0) {
  993. document.SetSelectionToCaret(true);
  994. } else {
  995. document.SetSelectionToCaret(false);
  996. }
  997. CaretMoved(this, null);
  998. return true;
  999. }
  1000. case Keys.Home: {
  1001. if ((Control.ModifierKeys & Keys.Control) != 0) {
  1002. document.MoveCaret(CaretDirection.CtrlHome);
  1003. } else {
  1004. document.MoveCaret(CaretDirection.Home);
  1005. }
  1006. if ((Control.ModifierKeys & Keys.Shift) == 0) {
  1007. document.SetSelectionToCaret(true);
  1008. } else {
  1009. document.SetSelectionToCaret(false);
  1010. }
  1011. CaretMoved(this, null);
  1012. return true;
  1013. }
  1014. case Keys.End: {
  1015. if ((Control.ModifierKeys & Keys.Control) != 0) {
  1016. document.MoveCaret(CaretDirection.CtrlEnd);
  1017. } else {
  1018. document.MoveCaret(CaretDirection.End);
  1019. }
  1020. if ((Control.ModifierKeys & Keys.Shift) == 0) {
  1021. document.SetSelectionToCaret(true);
  1022. } else {
  1023. document.SetSelectionToCaret(false);
  1024. }
  1025. CaretMoved(this, null);
  1026. return true;
  1027. }
  1028. case Keys.Enter: {
  1029. // ignoring accepts_return, fixes bug #76355
  1030. if (!read_only && document.multiline && (accepts_return || (FindForm() != null && FindForm().AcceptButton == null) || ((Control.ModifierKeys & Keys.Control) != 0))) {
  1031. Line line;
  1032. if (document.selection_visible) {
  1033. document.ReplaceSelection("\n", false);
  1034. }
  1035. line = document.CaretLine;
  1036. document.Split (document.CaretLine, document.CaretTag, document.CaretPosition);
  1037. line.ending = LineEnding.Rich;
  1038. document.InsertString (line, line.text.Length,
  1039. document.LineEndingToString (line.ending));
  1040. OnTextChanged(EventArgs.Empty);
  1041. document.UpdateView (line, document.Lines - line.line_no, 0);
  1042. CaretMoved(this, null);
  1043. return true;
  1044. }
  1045. break;
  1046. }
  1047. case Keys.Tab: {
  1048. if (!read_only && accepts_tab && document.multiline) {
  1049. document.InsertChar(document.CaretLine, document.CaretPosition, '\t');
  1050. if (document.selection_visible) {
  1051. document.ReplaceSelection("", false);
  1052. }
  1053. document.SetSelectionToCaret(true);
  1054. OnTextChanged(EventArgs.Empty);
  1055. CaretMoved(this, null);
  1056. return true;
  1057. }
  1058. break;
  1059. }
  1060. case Keys.PageUp: {
  1061. if ((Control.ModifierKeys & Keys.Control) != 0) {
  1062. document.MoveCaret(CaretDirection.CtrlPgUp);
  1063. } else {
  1064. document.MoveCaret(CaretDirection.PgUp);
  1065. }
  1066. document.DisplayCaret ();
  1067. return true;
  1068. }
  1069. case Keys.PageDown: {
  1070. if ((Control.ModifierKeys & Keys.Control) != 0) {
  1071. document.MoveCaret(CaretDirection.CtrlPgDn);
  1072. } else {
  1073. document.MoveCaret(CaretDirection.PgDn);
  1074. }
  1075. document.DisplayCaret ();
  1076. return true;
  1077. }
  1078. }
  1079. return false;
  1080. }
  1081. private void HandleBackspace(bool control) {
  1082. bool fire_changed;
  1083. fire_changed = false;
  1084. // delete only deletes on the line, doesn't do the combine
  1085. if (document.selection_visible) {
  1086. document.undo.BeginUserAction (Locale.GetText ("Delete"));
  1087. document.ReplaceSelection("", false);
  1088. document.undo.EndUserAction ();
  1089. fire_changed = true;
  1090. }
  1091. document.SetSelectionToCaret(true);
  1092. if (document.CaretPosition == 0) {
  1093. if (document.CaretLine.LineNo > 1) {
  1094. Line line;
  1095. int new_caret_pos;
  1096. line = document.GetLine(document.CaretLine.LineNo - 1);
  1097. new_caret_pos = line.TextLengthWithoutEnding ();
  1098. // Invalidate the old line position before we do the combine
  1099. document.Invalidate (line, 0, line, line.text.Length);
  1100. document.Combine(line, document.CaretLine);
  1101. document.UpdateView(line, document.Lines - line.LineNo, 0);
  1102. document.PositionCaret(line, new_caret_pos);
  1103. document.SetSelectionToCaret (true);
  1104. document.UpdateCaret();
  1105. fire_changed = true;
  1106. }
  1107. } else {
  1108. if (!control || document.CaretPosition == 0) {
  1109. // Move before we delete because the delete will change positions around
  1110. // if we cross a wrap border
  1111. LineTag tag = document.CaretTag;
  1112. int pos = document.CaretPosition;
  1113. document.MoveCaret (CaretDirection.CharBack);
  1114. document.DeleteChar (tag, pos, false);
  1115. document.SetSelectionToCaret (true);
  1116. } else {
  1117. int start_pos;
  1118. start_pos = document.CaretPosition - 1;
  1119. while ((start_pos > 0) && !Document.IsWordSeparator(document.CaretLine.Text[start_pos - 1])) {
  1120. start_pos--;
  1121. }
  1122. document.undo.BeginUserAction (Locale.GetText ("Delete"));
  1123. document.DeleteChars(document.CaretTag, start_pos, document.CaretPosition - start_pos);
  1124. document.undo.EndUserAction ();
  1125. document.PositionCaret(document.CaretLine, start_pos);
  1126. document.SetSelectionToCaret (true);
  1127. }
  1128. document.UpdateCaret();
  1129. fire_changed = true;
  1130. }
  1131. if (fire_changed) {
  1132. OnTextChanged(EventArgs.Empty);
  1133. }
  1134. CaretMoved(this, null);
  1135. }
  1136. protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {
  1137. // Make sure we don't get sized bigger than we want to be
  1138. if (!richtext) {
  1139. if (!document.multiline) {
  1140. if (height != PreferredHeight) {
  1141. requested_height = height;
  1142. height = PreferredHeight;
  1143. }
  1144. }
  1145. }
  1146. base.SetBoundsCore (x, y, width, height, specified);
  1147. }
  1148. protected override void WndProc(ref Message m) {
  1149. switch ((Msg)m.Msg) {
  1150. case Msg.WM_KEYDOWN: {
  1151. if (ProcessKeyMessage(ref m) || ProcessKey((Keys)m.WParam.ToInt32() | XplatUI.State.ModifierKeys)) {
  1152. m.Result = IntPtr.Zero;
  1153. return;
  1154. }
  1155. DefWndProc (ref m);
  1156. return;
  1157. }
  1158. case Msg.WM_CHAR: {
  1159. int ch;
  1160. if (ProcessKeyMessage(ref m)) {
  1161. m.Result = IntPtr.Zero;
  1162. return;
  1163. }
  1164. if (read_only) {
  1165. return;
  1166. }
  1167. m.Result = IntPtr.Zero;
  1168. ch = m.WParam.ToInt32();
  1169. if (ch == 127) {
  1170. HandleBackspace(true);
  1171. } else if (ch >= 32) {
  1172. if (document.selection_visible) {
  1173. document.ReplaceSelection("", false);
  1174. }
  1175. char c = (char)m.WParam;
  1176. switch (character_casing) {
  1177. case CharacterCasing.Upper:
  1178. c = Char.ToUpper((char) m.WParam);
  1179. break;
  1180. case CharacterCasing.Lower:
  1181. c = Char.ToLower((char) m.WParam);
  1182. break;
  1183. }
  1184. if (document.Length < max_length) {
  1185. document.InsertCharAtCaret(c, true);
  1186. #if NET_2_0
  1187. OnTextUpdate ();
  1188. #endif
  1189. OnTextChanged(EventArgs.Empty);
  1190. CaretMoved(this, null);
  1191. } else {
  1192. XplatUI.AudibleAlert();
  1193. }
  1194. return;
  1195. } else if (ch == 8) {
  1196. HandleBackspace(false);
  1197. }
  1198. return;
  1199. }
  1200. case Msg.WM_SETFOCUS:
  1201. base.WndProc(ref m);
  1202. document.CaretHasFocus ();
  1203. break;
  1204. case Msg.WM_KILLFOCUS:
  1205. base.WndProc(ref m);
  1206. document.CaretLostFocus ();
  1207. break;
  1208. default:
  1209. base.WndProc(ref m);
  1210. return;
  1211. }
  1212. }
  1213. #endregion // Protected Instance Methods
  1214. #region Events
  1215. static object AcceptsTabChangedEvent = new object ();
  1216. static object AutoSizeChangedEvent = new object ();
  1217. static object BorderStyleChangedEvent = new object ();
  1218. static object HideSelectionChangedEvent = new object ();
  1219. static object ModifiedChangedEvent = new object ();
  1220. static object MultilineChangedEvent = new object ();
  1221. static object ReadOnlyChangedEvent = new object ();
  1222. static object HScrolledEvent = new object ();
  1223. static object VScrolledEvent = new object ();
  1224. public event EventHandler AcceptsTabChanged {
  1225. add { Events.AddHandler (AcceptsTabChangedEvent, value); }
  1226. remove { Events.RemoveHandler (AcceptsTabChangedEvent, value); }
  1227. }
  1228. public new event EventHandler AutoSizeChanged {
  1229. add { Events.AddHandler (AutoSizeChangedEvent, value); }
  1230. remove { Events.RemoveHandler (AutoSizeChangedEvent, value); }
  1231. }
  1232. public event EventHandler BorderStyleChanged {
  1233. add { Events.AddHandler (BorderStyleChangedEvent, value); }
  1234. remove { Events.RemoveHandler (BorderStyleChangedEvent, value); }
  1235. }
  1236. public event EventHandler HideSelectionChanged {
  1237. add { Events.AddHandler (HideSelectionChangedEvent, value); }
  1238. remove { Events.RemoveHandler (HideSelectionChangedEvent, value); }
  1239. }
  1240. public event EventHandler ModifiedChanged {
  1241. add { Events.AddHandler (ModifiedChangedEvent, value); }
  1242. remove { Events.RemoveHandler (ModifiedChangedEvent, value); }
  1243. }
  1244. public event EventHandler MultilineChanged {
  1245. add { Events.AddHandler (MultilineChangedEvent, value); }
  1246. remove { Events.RemoveHandler (MultilineChangedEvent, value); }
  1247. }
  1248. public event EventHandler ReadOnlyChanged {
  1249. add { Events.AddHandler (ReadOnlyChangedEvent, value); }
  1250. remove { Events.RemoveHandler (ReadOnlyChangedEvent, value); }
  1251. }
  1252. internal event EventHandler HScrolled {
  1253. add { Events.AddHandler (HScrolledEvent, value); }
  1254. remove { Events.RemoveHandler (HScrolledEvent, value); }
  1255. }
  1256. internal event EventHandler VScrolled {
  1257. add { Events.AddHandler (VScrolledEvent, value); }
  1258. remove { Events.RemoveHandler (VScrolledEvent, value); }
  1259. }
  1260. [Browsable(false)]
  1261. [EditorBrowsable(EditorBrowsableState.Never)]
  1262. public new event EventHandler BackgroundImageChanged {
  1263. add { base.BackgroundImageChanged += value; }
  1264. remove { base.BackgroundImageChanged -= value; }
  1265. }
  1266. [Browsable(false)]
  1267. [EditorBrowsable(EditorBrowsableState.Advanced)]
  1268. public new event EventHandler Click {
  1269. add { base.Click += value; }
  1270. remove { base.Click -= value; }
  1271. }
  1272. // XXX should this not manipulate base.Paint?
  1273. [Browsable(false)]
  1274. [EditorBrowsable(EditorBrowsableState.Never)]
  1275. public new event PaintEventHandler Paint;
  1276. #endregion // Events
  1277. #region Private Methods
  1278. internal Document Document {
  1279. get {
  1280. return document;
  1281. }
  1282. set {
  1283. document = value;
  1284. }
  1285. }
  1286. internal bool ShowSelection {
  1287. get {
  1288. if (show_selection || !hide_selection) {
  1289. return true;
  1290. }
  1291. return has_focus;
  1292. }
  1293. set {
  1294. if (show_selection == value)
  1295. return;
  1296. show_selection = value;
  1297. // Currently InvalidateSelectionArea is commented out so do a full invalidate
  1298. document.InvalidateSelectionArea();
  1299. }
  1300. }
  1301. internal Graphics CreateGraphicsInternal() {
  1302. if (IsHandleCreated) {
  1303. return base.CreateGraphics();
  1304. }
  1305. return Graphics.FromImage(bmp);
  1306. }
  1307. internal override void OnPaintInternal (PaintEventArgs pevent) {
  1308. // Fill background
  1309. if (backcolor_set || (Enabled && !read_only)) {
  1310. pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), pevent.ClipRectangle);
  1311. } else {
  1312. pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(ThemeEngine.Current.ColorControl), pevent.ClipRectangle);
  1313. }
  1314. // Draw the viewable document
  1315. document.Draw(pevent.Graphics, pevent.ClipRectangle);
  1316. //
  1317. // OnPaint does not get raised on MS (see bug #80639)
  1318. //
  1319. pevent.Handled = true;
  1320. }
  1321. private void FixupHeight ()
  1322. {
  1323. if (!richtext) {
  1324. if (!document.multiline) {
  1325. if (PreferredHeight != ClientSize.Height) {
  1326. ClientSize = new Size (ClientSize.Width, PreferredHeight);
  1327. }
  1328. }
  1329. }
  1330. }
  1331. private bool IsDoubleClick (MouseEventArgs e)
  1332. {
  1333. TimeSpan interval = DateTime.Now - click_last;
  1334. if (interval.TotalMilliseconds > SystemInformation.DoubleClickTime)
  1335. return false;
  1336. Size dcs = SystemInformation.DoubleClickSize;
  1337. if (e.X < click_point_x - dcs.Width / 2 || e.X > click_point_x + dcs.Width / 2)
  1338. return false;
  1339. if (e.Y < click_point_y - dcs.Height / 2 || e.Y > click_point_y + dcs.Height / 2)
  1340. return false;
  1341. return true;
  1342. }
  1343. private void TextBoxBase_MouseDown (object sender, MouseEventArgs e)
  1344. {
  1345. if (e.Button == MouseButtons.Left) {
  1346. document.PositionCaret(e.X + document.ViewPortX, e.Y + document.ViewPortY);
  1347. if (IsDoubleClick (e)) {
  1348. switch (click_mode) {
  1349. case CaretSelection.Position:
  1350. SelectWord ();
  1351. click_mode = CaretSelection.Word;
  1352. break;
  1353. case CaretSelection.Word:
  1354. if (this is TextBox) {
  1355. document.SetSelectionToCaret (true);
  1356. click_mode = CaretSelection.Position;
  1357. break;
  1358. }
  1359. document.ExpandSelection (CaretSelection.Line, false);
  1360. click_mode = CaretSelection.Line;
  1361. break;
  1362. case CaretSelection.Line:
  1363. // Gotta do this first because Exanding to a word
  1364. // from a line doesn't really work
  1365. document.SetSelectionToCaret (true);
  1366. SelectWord ();
  1367. click_mode = CaretSelection.Word;
  1368. break;
  1369. }
  1370. } else {
  1371. document.SetSelectionToCaret (true);
  1372. click_mode = CaretSelection.Position;
  1373. }
  1374. click_point_x = e.X;
  1375. click_point_y = e.Y;
  1376. click_last = DateTime.Now;
  1377. }
  1378. if ((e.Button == MouseButtons.Middle) && (((int)Environment.OSVersion.Platform == 4) || ((int)Environment.OSVersion.Platform == 128))) {
  1379. Document.Marker marker;
  1380. marker.tag = document.FindCursor(e.X + document.ViewPortX, e.Y + document.ViewPortY, out marker.pos);
  1381. marker.line = marker.tag.line;
  1382. marker.height = marker.tag.height;
  1383. document.SetSelection(marker.line, marker.pos, marker.line, marker.pos);
  1384. Paste (Clipboard.GetDataObject (true), null, true);
  1385. }
  1386. }
  1387. private void TextBoxBase_MouseUp(object sender, MouseEventArgs e) {
  1388. if (e.Button == MouseButtons.Left) {
  1389. if (click_mode == CaretSelection.Position) {
  1390. document.SetSelectionToCaret(false);
  1391. document.DisplayCaret();
  1392. }
  1393. if (scroll_timer != null) {
  1394. scroll_timer.Enabled = false;
  1395. }
  1396. return;
  1397. }
  1398. }
  1399. private void PositionControls ()
  1400. {
  1401. if (hscroll.Visible) {
  1402. //vscroll.Maximum += hscroll.Height;
  1403. canvas_height = ClientSize.Height - hscroll.Height;
  1404. } else {
  1405. canvas_height = ClientSize.Height;
  1406. }
  1407. if (vscroll.Visible) {
  1408. //hscroll.Maximum += vscroll.Width;
  1409. canvas_width = ClientSize.Width - vscroll.Width;
  1410. } else {
  1411. canvas_width = ClientSize.Width;
  1412. }
  1413. document.ViewPortWidth = canvas_width;
  1414. document.ViewPortHeight = canvas_height;
  1415. if (canvas_height < 1 || canvas_width < 1)
  1416. return;
  1417. // We always move them, they just might not be displayed
  1418. hscroll.Bounds = new Rectangle (ClientRectangle.Left,
  1419. Math.Max (0, ClientRectangle.Height - hscroll.Height),
  1420. Math.Max (0, ClientSize.Width - (vscroll.Visible ? vscroll.Width : 0)),
  1421. hscroll.Height);
  1422. vscroll.Bounds = new Rectangle (Math.Max (0, ClientRectangle.Right - vscroll.Width),
  1423. ClientRectangle.Top, vscroll.Width,
  1424. Math.Max (0, ClientSize.Height - (hscroll.Visible ? hscroll.Height : 0)));
  1425. }
  1426. private void TextBoxBase_SizeChanged(object sender, EventArgs e) {
  1427. if (IsHandleCreated)
  1428. CalculateDocument ();
  1429. }
  1430. private void TextBoxBase_MouseWheel(object sender, MouseEventArgs e) {
  1431. if (!vscroll.Enabled) {
  1432. return;
  1433. }
  1434. if (e.Delta < 0)
  1435. vscroll.Value = Math.Min (vscroll.Value + SystemInformation.MouseWheelScrollLines * 5,
  1436. Math.Max (0, vscroll.Maximum - document.ViewPortHeight + 1));
  1437. else
  1438. vscroll.Value = Math.Max (0, vscroll.Value - SystemInformation.MouseWheelScrollLines * 5);
  1439. }
  1440. internal virtual void SelectWord ()
  1441. {
  1442. StringBuilder s = document.caret.line.text;
  1443. int start = document.caret.pos;
  1444. int end = document.caret.pos;
  1445. if (s.Length < 1) {
  1446. if (document.caret.line.line_no >= document.Lines)
  1447. return;
  1448. Line line = document.GetLine (document.caret.line.line_no + 1);
  1449. document.PositionCaret (line, 0);
  1450. return;
  1451. }
  1452. if (start > 0) {
  1453. start--;
  1454. end--;
  1455. }
  1456. // skip whitespace until we hit a word
  1457. while (start > 0 && s [start] == ' ')
  1458. start--;
  1459. if (start > 0) {
  1460. while (start > 0 && (s [start] != ' '))
  1461. start--;
  1462. if (s [start] == ' ')
  1463. start++;
  1464. }
  1465. if (s [end] == ' ') {
  1466. while (end < s.Length && s [end] == ' ')
  1467. end++;
  1468. } else {
  1469. while (end < s.Length && s [end] != ' ')
  1470. end++;
  1471. while (end < s.Length && s [end] == ' ')
  1472. end++;
  1473. }
  1474. document.SetSelection (document.caret.line, start, document.caret.line, end);
  1475. document.PositionCaret (document.selection_end.line, document.selection_end.pos);
  1476. document.DisplayCaret();
  1477. }
  1478. internal void CalculateDocument()
  1479. {
  1480. CalculateScrollBars ();
  1481. document.RecalculateDocument (CreateGraphicsInternal ());
  1482. if (document.caret.line != null && document.caret.line.Y < document.ViewPortHeight) {
  1483. // The window has probably been resized, making the entire thing visible, so
  1484. // we need to set the scroll position back to zero.
  1485. vscroll.Value = 0;
  1486. }
  1487. Invalidate();
  1488. }
  1489. internal void CalculateScrollBars () {
  1490. // FIXME - need separate calculations for center and right alignment
  1491. //
  1492. if (document.Width >= document.ViewPortWidth) {
  1493. hscroll.SetValues (0, Math.Max (1, document.Width), -1,
  1494. document.ViewPortWidth < 0 ? 0 : document.ViewPortWidth);
  1495. if (document.multiline)
  1496. hscroll.Enabled = true;
  1497. } else {
  1498. hscroll.Enabled = false;
  1499. hscroll.Maximum = document.ViewPortWidth;
  1500. }
  1501. if (document.Height >= document.ViewPortHeight) {
  1502. vscroll.SetValues (0, Math.Max (1, document.Height), -1,
  1503. document.ViewPortHeight < 0 ? 0 : document.ViewPortHeight);
  1504. if (document.multiline)
  1505. vscroll.Enabled = true;
  1506. } else {
  1507. vscroll.Enabled = false;
  1508. vscroll.Maximum = document.ViewPortHeight;
  1509. }
  1510. if (!WordWrap) {
  1511. switch (scrollbars) {
  1512. case RichTextBoxScrollBars.Both:
  1513. case RichTextBoxScrollBars.Horizontal:
  1514. hscroll.Visible = hscroll.Enabled;
  1515. break;
  1516. case RichTextBoxScrollBars.ForcedBoth:
  1517. case RichTextBoxScrollBars.ForcedHorizontal:
  1518. hscroll.Visible = true;
  1519. break;
  1520. default:
  1521. hscroll.Visible = false;
  1522. break;
  1523. }
  1524. } else {
  1525. hscroll.Visible = false;
  1526. }
  1527. switch (scrollbars) {
  1528. case RichTextBoxScrollBars.Both:
  1529. case RichTextBoxScrollBars.Vertical:
  1530. vscroll.Visible = vscroll.Enabled;
  1531. break;
  1532. case RichTextBoxScrollBars.ForcedBoth:
  1533. case RichTextBoxScrollBars.ForcedVertical:
  1534. vscroll.Visible = true;
  1535. break;
  1536. default:
  1537. vscroll.Visible = false;
  1538. break;
  1539. }
  1540. PositionControls ();
  1541. }
  1542. private void document_WidthChanged(object sender, EventArgs e) {
  1543. CalculateScrollBars();
  1544. }
  1545. private void document_HeightChanged(object sender, EventArgs e) {
  1546. CalculateScrollBars();
  1547. }
  1548. private void hscroll_ValueChanged(object sender, EventArgs e) {
  1549. int old_viewport_x;
  1550. old_viewport_x = document.ViewPortX;
  1551. document.ViewPortX = this.hscroll.Value;
  1552. //
  1553. // Before scrolling we want to destroy the caret, then draw a new one after the scroll
  1554. // the reason for this is that scrolling changes the coordinates of the caret, and we
  1555. // will get tracers if we don't
  1556. //
  1557. if (Focused)
  1558. document.CaretLostFocus ();
  1559. if (vscroll.Visible) {
  1560. XplatUI.ScrollWindow(this.Handle, new Rectangle(0, 0, ClientSize.Width - vscroll.Width, ClientSize.Height), old_viewport_x - this.hscroll.Value, 0, false);
  1561. } else {
  1562. XplatUI.ScrollWindow(this.Handle, ClientRectangle, old_viewport_x - this.hscroll.Value, 0, false);
  1563. }
  1564. if (Focused)
  1565. document.CaretHasFocus ();
  1566. EventHandler eh = (EventHandler)(Events [HScrolledEvent]);
  1567. if (eh != null)
  1568. eh (this, EventArgs.Empty);
  1569. }
  1570. private void vscroll_ValueChanged(object sender, EventArgs e) {
  1571. int old_viewport_y;
  1572. old_viewport_y = document.ViewPortY;
  1573. document.ViewPortY = this.vscroll.Value;
  1574. //
  1575. // Before scrolling we want to destroy the caret, then draw a new one after the scroll
  1576. // the reason for this is that scrolling changes the coordinates of the caret, and we
  1577. // will get tracers if we don't
  1578. //
  1579. if (Focused)
  1580. document.CaretLostFocus ();
  1581. if (hscroll.Visible) {
  1582. XplatUI.ScrollWindow(this.Handle, new Rectangle(0, 0, ClientSize.Width, ClientSize.Height - hscroll.Height), 0, old_viewport_y - this.vscroll.Value, false);
  1583. } else {
  1584. XplatUI.ScrollWindow(this.Handle, ClientRectangle, 0, old_viewport_y - this.vscroll.Value, false);
  1585. }
  1586. if (Focused)
  1587. document.CaretHasFocus ();
  1588. EventHandler eh = (EventHandler)(Events [VScrolledEvent]);
  1589. if (eh != null)
  1590. eh (this, EventArgs.Empty);
  1591. }
  1592. private void TextBoxBase_MouseMove(object sender, MouseEventArgs e) {
  1593. // FIXME - handle auto-scrolling if mouse is to the right/left of the window
  1594. if (e.Button == MouseButtons.Left && Capture) {
  1595. if (!ClientRectangle.Contains (e.X, e.Y)) {
  1596. if (scroll_timer == null) {
  1597. scroll_timer = new Timer ();
  1598. scroll_timer.Interval = 100;
  1599. scroll_timer.Tick += new EventHandler (ScrollTimerTickHandler);
  1600. }
  1601. if (!scroll_timer.Enabled) {
  1602. scroll_timer.Start ();
  1603. // Force the first tick
  1604. ScrollTimerTickHandler (null, EventArgs.Empty);
  1605. }
  1606. }
  1607. document.PositionCaret(e.X + document.ViewPortX, e.Y + document.ViewPortY);
  1608. if (click_mode == CaretSelection.Position) {
  1609. document.SetSelectionToCaret(false);
  1610. document.DisplayCaret();
  1611. }
  1612. }
  1613. }
  1614. private void TextBoxBase_FontOrColorChanged(object sender, EventArgs e) {
  1615. if (!richtext) {
  1616. Line line;
  1617. document.SuspendRecalc ();
  1618. // Font changes apply to the whole document
  1619. for (int i = 1; i <= document.Lines; i++) {
  1620. line = document.GetLine(i);
  1621. LineTag.FormatText(line, 1, line.text.Length, Font,
  1622. ThemeEngine.Current.ResPool.GetSolidBrush(ForeColor),
  1623. null, FormatSpecified.Font | FormatSpecified.Color);
  1624. }
  1625. document.ResumeRecalc (false);
  1626. // Make sure the caret height is matching the new font height
  1627. document.AlignCaret();
  1628. }
  1629. }
  1630. private void ScrollTimerTickHandler (object sender, EventArgs e)
  1631. {
  1632. Point pt = Cursor.Position;
  1633. pt = PointToClient (pt);
  1634. if (pt.X < ClientRectangle.Left) {
  1635. document.MoveCaret(CaretDirection.CharBackNoWrap);
  1636. document.SetSelectionToCaret(false);
  1637. CaretMoved(this, null);
  1638. } else if (pt.X > ClientRectangle.Right) {
  1639. document.MoveCaret(CaretDirection.CharForwardNoWrap);
  1640. document.SetSelectionToCaret(false);
  1641. CaretMoved(this, null);
  1642. } else if (pt.Y > ClientRectangle.Bottom) {
  1643. document.MoveCaret(CaretDirection.LineDown);
  1644. document.SetSelectionToCaret(false);
  1645. CaretMoved(this, null);
  1646. } else if (pt.Y < ClientRectangle.Top) {
  1647. document.MoveCaret(CaretDirection.LineUp);
  1648. document.SetSelectionToCaret(false);
  1649. CaretMoved(this, null);
  1650. }
  1651. }
  1652. /// <summary>Ensure the caret is always visible</summary>
  1653. internal void CaretMoved(object sender, EventArgs e) {
  1654. Point pos;
  1655. int height;
  1656. if (!IsHandleCreated || canvas_width < 1 || canvas_height < 1)
  1657. return;
  1658. document.MoveCaretToTextTag ();
  1659. pos = document.Caret;
  1660. //Console.WriteLine("Caret now at {0} (Thumb: {1}x{2}, Canvas: {3}x{4}, Document {5}x{6})", pos, hscroll.Value, vscroll.Value, canvas_width, canvas_height, document.Width, document.Height);
  1661. // Horizontal scrolling:
  1662. // If the caret moves to the left outside the visible area, we jump the document into view, not just one
  1663. // character, but 1/3 of the width of the document
  1664. // If the caret moves to the right outside the visible area, we scroll just enough to keep the caret visible
  1665. // Handle horizontal scrolling
  1666. if (document.CaretLine.alignment == HorizontalAlignment.Left) {
  1667. // Check if we moved out of view to the left
  1668. if (pos.X < (document.ViewPortX)) {
  1669. do {
  1670. if ((hscroll.Value - document.ViewPortWidth / 3) >= hscroll.Minimum) {
  1671. hscroll.Value -= document.ViewPortWidth / 3;
  1672. } else {
  1673. hscroll.Value = hscroll.Minimum;
  1674. }
  1675. } while (hscroll.Value > pos.X);
  1676. }
  1677. // Check if we moved out of view to the right
  1678. if ((pos.X >= (document.ViewPortWidth + document.ViewPortX)) && (hscroll.Value != hscroll.Maximum)) {
  1679. if ((pos.X - document.ViewPortWidth + 1) <= hscroll.Maximum) {
  1680. if (pos.X - document.ViewPortWidth >= 0) {
  1681. hscroll.Value = pos.X - document.ViewPortWidth + 1;
  1682. } else {
  1683. hscroll.Value = 0;
  1684. }
  1685. } else {
  1686. hscroll.Value = hscroll.Maximum;
  1687. }
  1688. }
  1689. } else if (document.CaretLine.alignment == HorizontalAlignment.Right) {
  1690. // hscroll.Value = pos.X;
  1691. // if ((pos.X > (this.canvas_width + document.ViewPortX)) && (hscroll.Enabled && (hscroll.Value != hscroll.Maximum))) {
  1692. // hscroll.Value = hscroll.Maximum;
  1693. // }
  1694. } else {
  1695. // FIXME - implement center cursor alignment
  1696. }
  1697. if (!document.multiline) {
  1698. return;
  1699. }
  1700. // Handle vertical scrolling
  1701. height = document.CaretLine.Height + 1;
  1702. if (pos.Y < document.ViewPortY) {
  1703. vscroll.Value = pos.Y;
  1704. }
  1705. if ((pos.Y + height) > (document.ViewPortY + canvas_height)) {
  1706. vscroll.Value = Math.Min (vscroll.Maximum, pos.Y - canvas_height + height);
  1707. }
  1708. }
  1709. internal bool Paste(IDataObject clip, DataFormats.Format format, bool obey_length) {
  1710. string s;
  1711. if (clip == null)
  1712. return false;
  1713. if (format == null) {
  1714. if ((this is RichTextBox) && clip.GetDataPresent(DataFormats.Rtf)) {
  1715. format = DataFormats.GetFormat(DataFormats.Rtf);
  1716. } else if ((this is RichTextBox) && clip.GetDataPresent (DataFormats.Bitmap)) {
  1717. format = DataFormats.GetFormat (DataFormats.Bitmap);
  1718. } else if (clip.GetDataPresent(DataFormats.UnicodeText)) {
  1719. format = DataFormats.GetFormat(DataFormats.UnicodeText);
  1720. } else if (clip.GetDataPresent(DataFormats.Text)) {
  1721. format = DataFormats.GetFormat(DataFormats.Text);
  1722. } else {
  1723. return false;
  1724. }
  1725. } else {
  1726. if ((format.Name == DataFormats.Rtf) && !(this is RichTextBox)) {
  1727. return false;
  1728. }
  1729. if (!clip.GetDataPresent(format.Name)) {
  1730. return false;
  1731. }
  1732. }
  1733. if (format.Name == DataFormats.Rtf) {
  1734. document.undo.BeginUserAction (Locale.GetText ("Paste"));
  1735. ((RichTextBox)this).SelectedRtf = (string)clip.GetData(DataFormats.Rtf);
  1736. document.undo.EndUserAction ();
  1737. return true;
  1738. } else if (format.Name == DataFormats.Bitmap) {
  1739. document.undo.BeginUserAction (Locale.GetText ("Paste"));
  1740. // document.InsertImage (document.caret.line, document.caret.pos, (Image) clip.GetData (DataFormats.Bitmap));
  1741. document.MoveCaret (CaretDirection.CharForward);
  1742. document.undo.EndUserAction ();
  1743. return true;
  1744. } else if (format.Name == DataFormats.UnicodeText) {
  1745. s = (string)clip.GetData(DataFormats.UnicodeText);
  1746. } else if (format.Name == DataFormats.Text) {
  1747. s = (string)clip.GetData(DataFormats.Text);
  1748. } else {
  1749. return false;
  1750. }
  1751. if (!obey_length) {
  1752. document.undo.BeginUserAction (Locale.GetText ("Paste"));
  1753. this.SelectedText = s;
  1754. document.undo.EndUserAction ();
  1755. } else {
  1756. if ((s.Length + document.Length) < max_length) {
  1757. document.undo.BeginUserAction (Locale.GetText ("Paste"));
  1758. this.SelectedText = s;
  1759. document.undo.EndUserAction ();
  1760. } else if (document.Length < max_length) {
  1761. document.undo.BeginUserAction (Locale.GetText ("Paste"));
  1762. this.SelectedText = s.Substring (0, max_length - document.Length);
  1763. document.undo.EndUserAction ();
  1764. }
  1765. }
  1766. return true;
  1767. }
  1768. internal abstract Color ChangeBackColor (Color backColor);
  1769. internal override bool IsInputCharInternal (char charCode)
  1770. {
  1771. return true;
  1772. }
  1773. #endregion // Private Methods
  1774. #if NET_2_0
  1775. // This is called just before OnTextChanged is called.
  1776. internal virtual void OnTextUpdate ()
  1777. {
  1778. }
  1779. protected override void OnTextChanged (EventArgs e)
  1780. {
  1781. base.OnTextChanged (e);
  1782. }
  1783. public virtual int GetLineFromCharIndex (int index)
  1784. {
  1785. Line line_out;
  1786. LineTag tag_out;
  1787. int pos;
  1788. document.CharIndexToLineTag (index, out line_out, out tag_out, out pos);
  1789. return line_out.LineNo;
  1790. }
  1791. protected override void OnMouseUp (MouseEventArgs e)
  1792. {
  1793. base.OnMouseUp (e);
  1794. }
  1795. #endif
  1796. }
  1797. }