Esempio n. 1
0
        ///<summary>Break a tag into two with identical attributes; pos is 1-based; returns tag starting at &gt;pos&lt; or null if end-of-line</summary>
        public LineTag Break(int pos)
        {
            LineTag new_tag;

#if DEBUG
            // Sanity
            if (pos < this.Start)
            {
                throw new Exception("Breaking at a negative point");
            }
#endif

#if DEBUG
            if (pos > End)
            {
                throw new Exception("Breaking past the end of a line");
            }
#endif

            new_tag = new LineTag(line, pos);
            new_tag.CopyFormattingFrom(this);

            new_tag.next     = this.next;
            this.next        = new_tag;
            new_tag.previous = this;

            if (new_tag.next != null)
            {
                new_tag.next.previous = new_tag;
            }

            return(new_tag);
        }
Esempio n. 2
0
		// start_pos = 1-based
		// end_pos = 1-based
		public Line Duplicate(Line start_line, int start_pos, Line end_line, int end_pos)
		{
			Line	ret;
			Line	line;
			Line	current;
			LineTag	tag;
			LineTag	current_tag;
			int	start;
			int	end;
			int	tag_start;

			line = new Line (start_line.document, start_line.ending);
			ret = line;

			for (int i = start_line.line_no; i <= end_line.line_no; i++) {
				current = document.GetLine(i);

				if (start_line.line_no == i) {
					start = start_pos;
				} else {
					start = 0;
				}

				if (end_line.line_no == i) {
					end = end_pos;
				} else {
					end = current.text.Length;
				}

				if (end_pos == 0)
					continue;

				// Text for the tag
				line.text = new StringBuilder (current.text.ToString (start, end - start));

				// Copy tags from start to start+length onto new line
				current_tag = current.FindTag (start + 1);
				while ((current_tag != null) && (current_tag.Start <= end)) {
					if ((current_tag.Start <= start) && (start < (current_tag.Start + current_tag.Length))) {
						// start tag is within this tag
						tag_start = start;
					} else {
						tag_start = current_tag.Start;
					}

					tag = new LineTag(line, tag_start - start + 1);
					tag.CopyFormattingFrom (current_tag);

					current_tag = current_tag.Next;

					// Add the new tag to the line
					if (line.tags == null) {
						line.tags = tag;
					} else {
						LineTag tail;
						tail = line.tags;

						while (tail.Next != null) {
							tail = tail.Next;
						}
						tail.Next = tag;
						tag.Previous = tail;
					}
				}

				if ((i + 1) <= end_line.line_no) {
					line.ending = current.ending;

					// Chain them (we use right/left as next/previous)
					line.right = new Line (start_line.document, start_line.ending);
					line.right.left = line;
					line = line.right;
				}
			}

			return ret;
		}
Esempio n. 3
0
		///<summary>Split line at given tag and position into two lines</summary>
		///if more space becomes available on previous line
		internal void Split(Line line, LineTag tag, int pos) {
			LineTag	new_tag;
			Line	new_line;
			bool	move_caret;
			bool	move_sel_start;
			bool	move_sel_end;

			move_caret = false;
			move_sel_start = false;
			move_sel_end = false;

#if DEBUG
			SanityCheck();

			if (tag.End < pos)
				throw new Exception ("Split called with the wrong tag");
#endif

			// Adjust selection and cursors
			if (caret.line == line && caret.pos >= pos) {
				move_caret = true;
			}
			if (selection_start.line == line && selection_start.pos > pos) {
				move_sel_start = true;
			}

			if (selection_end.line == line && selection_end.pos > pos) {
				move_sel_end = true;
			}

			// cover the easy case first
			if (pos == line.text.Length) {
				Add (line.line_no + 1, String.Empty, line.alignment, tag.Font, tag.Color, line.ending);

				new_line = GetLine (line.line_no + 1);
				
				if (move_caret) {
					caret.line = new_line;
					caret.tag = new_line.tags;
					caret.pos = 0;

					if (selection_visible == false) {
						SetSelectionToCaret (true);
					}
				}

				if (move_sel_start) {
					selection_start.line = new_line;
					selection_start.pos = 0;
					selection_start.tag = new_line.tags;
				}

				if (move_sel_end) {
					selection_end.line = new_line;
					selection_end.pos = 0;
					selection_end.tag = new_line.tags;
				}

#if DEBUG
				SanityCheck ();
#endif
				return;
			}

			// We need to move the rest of the text into the new line
			Add (line.line_no + 1, line.text.ToString (pos, line.text.Length - pos), line.alignment, tag.Font, tag.Color, line.ending);

			// Now transfer our tags from this line to the next
			new_line = GetLine(line.line_no + 1);

			line.recalc = true;
			new_line.recalc = true;

			//make sure that if we are at the end of a tag, we start on the begining
			//of a new one, if one exists... Stops us creating an empty tag and
			//make the operation easier.
			if (tag.Next != null && (tag.Next.Start - 1) == pos)
				tag = tag.Next;

			if ((tag.Start - 1) == pos) {
				int	shift;

				// We can simply break the chain and move the tag into the next line

				// if the tag we are moving is the first, create an empty tag
				// for the line we are leaving behind
				if (tag == line.tags) {
					new_tag = new LineTag(line, 1);
					new_tag.CopyFormattingFrom (tag);
					line.tags = new_tag;
				}

				if (tag.Previous != null) {
					tag.Previous.Next = null;
				}
				new_line.tags = tag;
				tag.Previous = null;
				tag.Line = new_line;

				// Walk the list and correct the start location of the tags we just bumped into the next line
				shift = tag.Start - 1;

				new_tag = tag;
				while (new_tag != null) {
					new_tag.Start -= shift;
					new_tag.Line = new_line;
					new_tag = new_tag.Next;
				}
			} else {
				int	shift;

				new_tag = new LineTag (new_line, 1);			
				new_tag.Next = tag.Next;
				new_tag.CopyFormattingFrom (tag);
				new_line.tags = new_tag;
				if (new_tag.Next != null) {
					new_tag.Next.Previous = new_tag;
				}
				tag.Next = null;

				shift = pos;
				new_tag = new_tag.Next;
				while (new_tag != null) {
					new_tag.Start -= shift;
					new_tag.Line = new_line;
					new_tag = new_tag.Next;

				}
			}

			if (move_caret) {
				caret.line = new_line;
				caret.pos = caret.pos - pos;
				caret.tag = caret.line.FindTag(caret.pos);

				if (selection_visible == false) {
					SetSelectionToCaret (true);
					move_sel_start = false;
					move_sel_end = false;
				}
			}

			if (move_sel_start) {
				selection_start.line = new_line;
				selection_start.pos = selection_start.pos - pos;
				if  (selection_start.Equals(selection_end))
					selection_start.tag = new_line.FindTag(selection_start.pos);
				else
					selection_start.tag = new_line.FindTag (selection_start.pos + 1);
			}

			if (move_sel_end) {
				selection_end.line = new_line;
				selection_end.pos = selection_end.pos - pos;
				selection_end.tag = new_line.FindTag(selection_end.pos);
			}

			CharCount -= line.text.Length - pos;
			line.text.Remove(pos, line.text.Length - pos);
#if DEBUG
			SanityCheck ();
#endif
		}
Esempio n. 4
0
		///<summary>Break a tag into two with identical attributes; pos is 1-based; returns tag starting at &gt;pos&lt; or null if end-of-line</summary>
		public LineTag Break (int pos)
		{
			LineTag	new_tag;

#if DEBUG
			// Sanity
			if (pos < this.Start)
				throw new Exception ("Breaking at a negative point");
#endif

#if DEBUG
			if (pos > End)
				throw new Exception ("Breaking past the end of a line");
#endif

			new_tag = new LineTag(line, pos);
			new_tag.CopyFormattingFrom (this);

			new_tag.next = this.next;
			this.next = new_tag;
			new_tag.previous = this;

			if (new_tag.next != null)
				new_tag.next.previous = new_tag;

			return new_tag;
		}