Ejemplo n.º 1
0
		internal void Insert (Line line, int pos, bool update_caret, string s)
		{
			Insert (line, pos, update_caret, s, line.FindTag (pos));
		}
Ejemplo n.º 2
0
		/// <summary>
		///  Scans the next paragraph for http:/ ftp:/ www. https:/ etc and marks the tags
		///  as links.
		/// </summary>
		/// <param name="start_line">The line to start on</param>
		/// <param name="link_changed">marks as true if something is changed</param>
		private void ScanForLinks (Line start_line, ref bool link_changed)
		{
			Line current_line = start_line;
			StringBuilder line_no_breaks = new StringBuilder ();
			StringBuilder line_link_record = new StringBuilder ();
			ArrayList cumulative_length_list = new ArrayList ();
			bool update_caret_tag = false;

			cumulative_length_list.Add (0);

			while (current_line != null) {
				line_no_breaks.Append (current_line.text);

				if (link_changed == false)
					current_line.LinkRecord (line_link_record);

				current_line.ClearLinks ();

				cumulative_length_list.Add (line_no_breaks.Length);

				if (current_line.ending == LineEnding.Wrap)
					current_line = GetLine (current_line.LineNo + 1);
				else
					break;
			}

			// search for protocols.. make sure www. is first!
			string [] search_terms = new string [] { "www.", "http:/", "ftp:/", "https:/" };
			int search_found = 0;
			int index_found = 0;
			string line_no_breaks_string = line_no_breaks.ToString ();
			int line_no_breaks_index = 0;
			int link_end = 0;

			while (true) {
				if (line_no_breaks_index >= line_no_breaks_string.Length)
					break;

				index_found = FirstIndexOfAny (line_no_breaks_string, search_terms, line_no_breaks_index, out search_found);

				//no links found on this line
				if (index_found == -1)
					break;

				if (search_found == 0) {
					// if we are at the end of the line to analyse and the end of the line
					// is "www." then there are no links here
					if (line_no_breaks_string.Length == index_found + search_terms [0].Length)
						break;

					// if after www. we don't have a letter a digit or a @ or - or /
					// then it is not a web address, we should continue searching
					if (char.IsLetterOrDigit (line_no_breaks_string [index_found + search_terms [0].Length]) == false &&
						"@/~".IndexOf (line_no_breaks_string [index_found + search_terms [0].Length].ToString ()) == -1) {
						line_no_breaks_index = index_found + search_terms [0].Length;
						continue;
					}
				}

				link_end = line_no_breaks_string.Length - 1;
				line_no_breaks_index = line_no_breaks_string.Length;

				// we've found a link, we just need to find where it ends now
				for (int i = index_found + search_terms [search_found].Length; i < line_no_breaks_string.Length; i++) {
					if (line_no_breaks_string [i - 1] == '.') {
						if (char.IsLetterOrDigit (line_no_breaks_string [i]) == false &&
							"@/~".IndexOf (line_no_breaks_string [i].ToString ()) == -1) {
							link_end = i - 1;
							line_no_breaks_index = i;
							break;
						}
					} else {
						if (char.IsLetterOrDigit (line_no_breaks_string [i]) == false &&
							"@-/:~.?=_&".IndexOf (line_no_breaks_string [i].ToString ()) == -1) {
							link_end = i - 1;
							line_no_breaks_index = i;
							break;
						}
					}
				}

				string link_text = line_no_breaks_string.Substring (index_found, link_end - index_found + 1);
				int current_cumulative = 0;

				// we've found a link - index_found -> link_end
				// now we just make all the tags as containing link and
				// point them to the text for the whole link

				current_line = start_line;

				//find the line we start on
				for (current_cumulative = 1; current_cumulative < cumulative_length_list.Count; current_cumulative++)
					if ((int)cumulative_length_list [current_cumulative] > index_found)
						break;

				current_line = GetLine (start_line.LineNo + current_cumulative - 1);

				// find the tag we start on
				LineTag current_tag = current_line.FindTag (index_found - (int)cumulative_length_list [current_cumulative - 1] + 1);

				if (current_tag.Start != (index_found - (int)cumulative_length_list [current_cumulative - 1]) + 1) {
					if (current_tag == CaretTag)
						update_caret_tag = true;

					current_tag = current_tag.Break ((index_found - (int)cumulative_length_list [current_cumulative - 1]) + 1);
				}

				// set the tag
				current_tag.IsLink = true;
				current_tag.LinkText = link_text;

				//go through each character
				// find the tag we are in
				// skip the number of characters in the tag
				for (int i = 1; i < link_text.Length; i++) {
					// on to a new word-wrapped line
					if ((int)cumulative_length_list [current_cumulative] <= index_found + i) {

						current_line = GetLine (start_line.LineNo + current_cumulative++);
						current_tag = current_line.FindTag (index_found + i - (int)cumulative_length_list [current_cumulative - 1] + 1);

						current_tag.IsLink = true;
						current_tag.LinkText = link_text;

						continue;
					}

					if (current_tag.End < index_found + 1 + i - (int)cumulative_length_list [current_cumulative - 1]) {
						// skip empty tags in the middle of the URL
						do {
							current_tag = current_tag.Next;
						} while (current_tag.Length == 0);

						current_tag.IsLink = true;
						current_tag.LinkText = link_text;
					}
				}

				//if there are characters left in the tag after the link
				// split the tag
				// make the second part a non link
				if (current_tag.End > (index_found + link_text.Length + 1) - (int)cumulative_length_list [current_cumulative - 1]) {
					if (current_tag == CaretTag)
						update_caret_tag = true;

					current_tag.Break ((index_found + link_text.Length + 1) - (int)cumulative_length_list [current_cumulative - 1]);
				}
			}

			if (update_caret_tag) {
				CaretTag = LineTag.FindTag (CaretLine, CaretPosition);
				link_changed = true;
			} else {
				if (link_changed == false) {
					current_line = start_line;
					StringBuilder new_link_record = new StringBuilder ();

					while (current_line != null) {
						current_line.LinkRecord (new_link_record);

						if (current_line.ending == LineEnding.Wrap)
							current_line = GetLine (current_line.LineNo + 1);
						else
							break;
					}

					if (new_link_record.Equals (line_link_record) == false)
						link_changed = true;
				}
			}
		}
Ejemplo n.º 3
0
		internal void PositionCaret(Line line, int pos) {
			caret.tag = line.FindTag (pos);

			MoveCaretToTextTag ();

			caret.line = line;
			caret.pos = pos;

			if (owner.IsHandleCreated) {
				if (owner.Focused) {
					if (caret.height != caret.tag.Height)
						XplatUI.CreateCaret (owner.Handle, caret_width, caret.height);
					XplatUI.SetCaretPos(owner.Handle, 
						offset_x + (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x, 
						offset_y + caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
				}

				if (CaretMoved != null) CaretMoved(this, EventArgs.Empty);
			}

			// We set this at the end because we use the heights to determine whether or
			// not we need to recreate the caret
			caret.height = caret.tag.Height;

		}