Ejemplo n.º 1
0
		internal void Combine(Line first, Line second) {
			LineTag	last;
			int	shift;

			// strip the ending off of the first lines text
			first.text.Length = first.text.Length - LineEndingLength (first.ending);

			// Combine the two tag chains into one
			last = first.tags;

			// Maintain the line ending style
			first.ending = second.ending;

			while (last.Next != null) {
				last = last.Next;
			}

			// need to get the shift before setting the next tag since that effects length
			shift = last.Start + last.Length - 1;
			last.Next = second.tags;
			last.Next.Previous = last;

			// Fix up references within the chain
			last = last.Next;
			while (last != null) {
				last.Line = first;
				last.Start += shift;
				last = last.Next;
			}

			// Combine both lines' strings
			first.text.Insert(first.text.Length, second.text.ToString());
			first.Grow(first.text.Length);

			// Remove the reference to our (now combined) tags from the doomed line
			second.tags = null;

			// Renumber lines
			DecrementLines(first.line_no + 2);	// first.line_no + 1 will be deleted, so we need to start renumbering one later

			// Mop up
			first.recalc = true;
			first.height = 0;	// This forces RecalcDocument/UpdateView to redraw from this line on
			first.Streamline(lines);

			// Update Caret, Selection, etc
			if (caret.line == second) {
				caret.Combine(first, shift);
			}
			if (selection_anchor.line == second) {
				selection_anchor.Combine(first, shift);
			}
			if (selection_start.line == second) {
				selection_start.Combine(first, shift);
			}
			if (selection_end.line == second) {
				selection_end.Combine(first, shift);
			}

			#if Debug
				Line	check_first;
				Line	check_second;

				check_first = GetLine(first.line_no);
				check_second = GetLine(check_first.line_no + 1);

				Console.WriteLine("Pre-delete: Y of first line: {0}, second line: {1}", check_first.Y, check_second.Y);
			#endif

			this.Delete(second);

			#if Debug
				check_first = GetLine(first.line_no);
				check_second = GetLine(check_first.line_no + 1);

				Console.WriteLine("Post-delete Y of first line: {0}, second line: {1}", check_first.Y, check_second.Y);
			#endif
		}
Ejemplo n.º 2
0
		// Insert multi-line text at the given position; use formatting at insertion point for inserted text
		internal void Insert(Line line, int pos, Line insert, bool select)
		{
			Line	current;
			LineTag	tag;
			int	offset;
			int	lines;
			Line	first;

			// Handle special case first
			if (insert.right == null) {

				// Single line insert
				document.Split(line, pos);

				if (insert.tags == null) {
					return;	// Blank line
				}

				//Insert our tags at the end
				tag = line.tags;

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

				offset = tag.Start + tag.Length - 1;

				tag.Next = insert.tags;
				line.text.Insert(offset, insert.text.ToString());

				// Adjust start locations
				tag = tag.Next;
				while (tag != null) {
					tag.Start += offset;
					tag.Line = line;
					tag = tag.Next;
				}
				// Put it back together
				document.Combine(line.line_no, line.line_no + 1);

				if (select) {
					document.SetSelectionStart (line, pos, false);
					document.SetSelectionEnd (line, pos + insert.text.Length, false);
				}

				document.UpdateView(line, pos);
				return;
			}

			first = line;
			lines = 1;
			current = insert;

			while (current != null) {

				if (current == insert) {
					// Inserting the first line we split the line (and make space)
					document.Split(line.line_no, pos);
					//Insert our tags at the end of the line
					tag = line.tags;

					
					if (tag != null && tag.Length != 0) {
						while (tag.Next != null) {
							tag = tag.Next;
						}
						offset = tag.Start + tag.Length - 1;
						tag.Next = current.tags;
						tag.Next.Previous = tag;

						tag = tag.Next;

					} else {
						offset = 0;
						line.tags = current.tags;
						line.tags.Previous = null;
						tag = line.tags;
					}

					line.ending = current.ending;
				} else {
					document.Split(line.line_no, 0);
					offset = 0;
					line.tags = current.tags;
					line.tags.Previous = null;
					line.ending = current.ending;
					tag = line.tags;
				}

				// Adjust start locations and line pointers
				while (tag != null) {
					tag.Start += offset - 1;
					tag.Line = line;
					tag = tag.Next;
				}

				line.text.Insert(offset, current.text.ToString());
				line.Grow(line.text.Length);

				line.recalc = true;
				line = document.GetLine(line.line_no + 1);

				// FIXME? Test undo of line-boundaries
				if ((current.right == null) && (current.tags.Length != 0)) {
					document.Combine(line.line_no - 1, line.line_no);
				}
				current = current.right;
				lines++;

			}

			// Recalculate our document
			document.UpdateView(first, lines, pos);
			return;
		}		
Ejemplo n.º 3
0
		internal void InsertPicture (Line line, int pos, RTF.Picture picture)
		{
			//LineTag next_tag;
			LineTag tag;
			int len;

			len = 1;

			// Just a place holder basically
			line.text.Insert (pos, "I");

			PictureTag picture_tag = new PictureTag (line, pos + 1, picture);

			tag = LineTag.FindTag (line, pos);
			picture_tag.CopyFormattingFrom (tag);
			/*next_tag = */tag.Break (pos + 1);
			picture_tag.Previous = tag;
			picture_tag.Next = tag.Next;
			tag.Next = picture_tag;

			//
			// Picture tags need to be surrounded by text tags
			//
			if (picture_tag.Next == null) {
				picture_tag.Next = new LineTag (line, pos + 1);
				picture_tag.Next.CopyFormattingFrom (tag);
				picture_tag.Next.Previous = picture_tag;
			}

			tag = picture_tag.Next;
			while (tag != null) {
				tag.Start += len;
				tag = tag.Next;
			}

			line.Grow (len);
			line.recalc = true;

			UpdateView (line, pos);
		}