if (Left != null)
for (i = Left; i.Right != null; i = i.Right);
else
- for (i = Parent; i != null && i.Left == null; i = i.Parent);
+ {
+ MInterval child = this;
+ for (i = Parent; i != null && i.Left == child;
+ child = i, i = i.Parent);
+ }
return i;
}
}
if (Right != null)
for (i = Right; i.Left != null; i = i.Left);
else
- for (i = Parent; i != null && i.Right == null; i = i.Parent);
+ {
+ MInterval child = this;
+ for (i = Parent; i != null && i.Right == child;
+ child = i, i = i.Parent);
+ }
return i;
}
}
right_copy = Right.Copy (To, end);
}
- copy = new MInterval (Key, mtext, end - start, Stack);
+ copy = new MInterval (Key, null, end - start, Stack);
remove_properties (MTextProperty.Flag.Sensitive);
copy.Left = left_copy;
copy.Right = right_copy;
}
}
+ private MInterval delete_node_forward ()
+ {
+ if (Parent != null)
+ {
+ int len = Length - RightLength;
+
+ for (MInterval i = Parent; i != null; i = i.Parent)
+ i.Length -= len;
+ if (Parent.Left == this)
+ Parent.Left = Right;
+ else
+ Parent.Right = Right;
+ }
+
+ if (Right != null)
+ {
+ Right.Parent = Parent;
+ return Right.LeftMost;
+ }
+ return Parent;
+ }
+
+ private MInterval delete_node_backward ()
+ {
+ if (Parent != null)
+ {
+ int len = Length - RightLength;
+
+ for (MInterval i = Parent; i != null; i = i.Parent)
+ i.Length -= len;
+ if (Parent.Left == this)
+ Parent.Left = Left;
+ else
+ Parent.Right = Left;
+ }
+
+ if (Left != null)
+ {
+ Left.Parent = Parent;
+ return Left.RightMost;
+ }
+ return Parent;
+ }
+
+ private void set_mtext (MText mt)
+ {
+ mtext = mt;
+ if (Left != null)
+ Left.set_mtext (mt);
+ if (Right != null)
+ Right.set_mtext (mt);
+ }
+
+ private MInterval graft (MInterval interval, bool forward, out int len)
+ {
+ MInterval i;
+
+ len = 0;
+ if (forward)
+ {
+ i = interval.LeftMost;
+ while (i != null)
+ {
+ if (! mergeable (i))
+ break;
+ len += i.Length - i.RightLength;
+ i = i.delete_node_forward ();
+ }
+ }
+ else
+ {
+ i = interval.RightMost;
+ while (i != null)
+ {
+ if (! mergeable (i))
+ break;
+ len += i.Length - i.LeftLength;
+ i = i.delete_node_backward ();
+ }
+ }
+
+ Length += len;
+ To += len;
+ for (MInterval prev = this, ii = this.Parent; ii != null;
+ prev = ii, ii = ii.Parent)
+ {
+ ii.Length += len;
+ if (prev == ii.Left)
+ {
+ ii.From += len;
+ ii.To += len;;
+ }
+ }
+ if (i != null)
+ while (i.Parent != null) i = i.Parent;
+ return i;
+ }
+
public void Insert (int pos, MInterval interval)
{
update_from_to ();
- Console.Write ("insert({0}) in ", pos); DumpOne (false, true);
+ Console.Write ("insert({0}) at {1} in ", interval.Length, pos);
+ DumpOne (false, true);
+
+ interval.set_mtext (mtext);
if (pos < From)
Prev.Insert (pos, interval);
else if (pos == From)
{
- if (pos > 0)
- {
- MInterval prev = Prev;
+ MInterval prev = Prev;
+ if (prev != null)
+ {
if (Left == null)
{
prev.Insert (pos, interval);
(MTextProperty.Flag.Sensitive|MTextProperty.Flag.FrontSticky);
interval.inherit_rear_properties (Stack);
- // INTERVAL is ready to insert.
- //
- // .-this-. ==> .-this-.
- // left-. left-.
- // child .-interval
- // child
-
- if (pos > 0)
+ int len;
+ interval = graft (interval, false, out len);
+ if (interval != null && prev != null)
+ interval = prev.graft (interval, true, out len);
+ if (interval != null)
{
- MInterval i = Left.RightMost;
-
- i.Left = interval;
+ MInterval i;
+
+ if (Left != null)
+ {
+ // .-this-. ==> .-this-.
+ // left-. .-left-.
+ // child child-.
+ // interval
+ i = Left.RightMost;
+ i.Right = interval;
+ }
+ else
+ {
+ Left = interval;
+ i = this;
+ }
interval.Parent = i;
for (; i != null; i = i.Parent)
i.Length += interval.Length;
}
- else
- {
- Left = interval;
-
- for (MInterval i = this; i != null; i = i.Parent)
- i.Length += interval.Length;
- }
}
else if (pos < To)
{
remove_properties (MTextProperty.Flag.Sensitive);
- divide_right (pos).Insert (pos, interval);
- }
+
+ int len;
+ interval = graft (interval, true, out len);
+ pos += len;
+ if (interval != null)
+ interval = graft (interval, false, out len);
+ if (interval != null)
+ {
+ divide_right (pos);
+ Right.Left = interval;
+ interval.Parent = Right;
+ for (MInterval i = Right; i != null; i = i.Parent)
+ i.Length += interval.Length;
+ }
+ }
else if (pos == To)
{
- if (pos < mtext.Length)
- {
- MInterval next = Next;
+ MInterval next = Next;
+ if (next != null)
+ {
if (Right == null)
{
next.Insert (pos, interval);
(MTextProperty.Flag.Sensitive|MTextProperty.Flag.RearSticky);
interval.inherit_front_properties (Stack);
- // INTERVAL is ready to insert.
- //
- // .-this-. ==> .-this-.
- // .-right .-right
- // child interval-.
- // child
-
- if (Right != null)
+ int len;
+ interval = graft (interval, true, out len);
+ if (interval != null && next != null)
+ interval = next.graft (interval, false, out len);
+ if (interval != null)
{
- MInterval i = Right.LeftMost;
-
- i.Left = interval;
+ MInterval i;
+
+ if (Right != null)
+ {
+ // .-this-. ==> .-this-.
+ // .-right .-right
+ // child .-child
+ // interval
+
+ i = Right.LeftMost;
+ i.Left = interval;
+ }
+ else
+ {
+ Right = interval;
+ i = this;
+ }
interval.Parent = i;
for (; i != null; i = i.Parent)
i.Length += interval.Length;
}
- else
- {
- Right = interval;
-
- for (MInterval i = this; i != null; i = i.Parent)
- i.Length += interval.Length;
- }
}
else // (pos > To)
Next.Insert (pos, interval);
interval.Parent = Parent;
if (Parent == null)
{
- mtext.intervals.Put (Key, interval);
+ if (mtext != null)
+ mtext.intervals.Put (Key, interval);
}
else
{
divide_right (end);
Stack.Pop ();
if (check_prev && Left != null)
- check_prev = try_merge_prev () && (Left == null);
+ check_prev = try_merge_prev () && (Left != null);
if (check_next && Right != null)
- check_next = try_merge_next () && (Right == null);
+ check_next = try_merge_next () && (Right != null);
if (check_prev)
{
if (Prev.try_merge_next () && check_next)