*** TextEd.c.orig Wed Feb 8 13:16:40 1995 --- TextEd.c Tue Mar 7 15:32:12 1995 *************** *** 2665,2671 **** int deleted; { long ref, position; ! int i, n; w->texted.mult = 1; ref = w->texted.cursor_position; --- 2665,2671 ---- int deleted; { long ref, position; ! int n; w->texted.mult = 1; ref = w->texted.cursor_position; *************** *** 2715,2729 **** XeTextRegion *r = &w->texted.regions[n]; if (r->mode == XeTextHighlight_UNUSED) continue; ! for (i = 0; i < XtNumber(r->range); ++i) ! if (ref <= r->range[i]) ! if (deleted == 0) ! r->range[i] += ! w->texted.cursor_position-ref; ! else if (ref + deleted > r->range[i]) ! r->range[i] = ref; ! else ! r->range[i] -= deleted; XeUpdateTextRegion(w, r, False); /* Should fine tune? --msa */ } ChangeWidgetSize(w, True); /* ..only if larger! */ --- 2715,2736 ---- XeTextRegion *r = &w->texted.regions[n]; if (r->mode == XeTextHighlight_UNUSED) continue; ! if (ref < r->range[0] || ! (ref == r->range[0] && r->range[0] < r->range[1])) ! if (deleted == 0) ! r->range[0] += w->texted.cursor_position-ref; ! else if (ref + deleted > r->range[0]) ! r->range[0] = ref; ! else ! r->range[0] -= deleted; ! if (ref < r->range[1] || ! (ref == r->range[1] && r->range[1] < r->range[0])) ! if (deleted == 0) ! r->range[1] += w->texted.cursor_position-ref; ! else if (ref + deleted > r->range[1]) ! r->range[1] = ref; ! else ! r->range[1] -= deleted; XeUpdateTextRegion(w, r, False); /* Should fine tune? --msa */ } ChangeWidgetSize(w, True); /* ..only if larger! */ *************** *** 3872,3878 **** --- 3879,3930 ---- _XeTextFeedContent(t->text.inserting, value, length); EndEditing(t, 0); } + + /* + ** XeTextChangeMode + ** first insert the (value, length) portion as in XeTextInsert, but + ** with side effect that any mode changes introduced by this text + ** will override even currently locked modes, and additionally all + ** touched attributes will be merged into the locked modes. If the + ** same locked attribute is touched multiple times, the last value + ** will remain locked. + ** + ** After insert, change the mode of amount characters counting from the + ** current insert point. Only modes that are currently locked in the + ** insert point are affected. + ** + ** This function does not move insert point, unless the (value, length) + ** contains something that cause it to be moved in the standard + ** 'XeTextInsert' manner. + ** + ** *NOTE* + ** Although the (value, length) can contain any string and works almost + ** like in XeTextInsert, the primary purpose of this function is that + ** the string contains only control sequences only affecting the mode. + */ + void XeTextChangeMode(w, value, length, amount) + Widget w; + char *value; + long length; + long amount; + { + XeTextEdWidget t = (XeTextEdWidget)w; + if (!IsTextEdWidget(w)) + return; + if (!StartEditing(t, XeTextInsertMode_CURRENT, (XEvent *)NULL)) + return; + if (length > 0 && value) + { + _XeTextLock(t->text.inserting, FALSE); + _XeTextFeedContent(t->text.inserting, value, length); + _XeTextLock(t->text.inserting, TRUE); + } + _XeTextChangeMode(t->text.inserting, amount); + EndEditing(t, 0); + } + + /* ** XeTextSetInsertionPosition ** move the current insert (cursor) position to the specified ** position. Current insert point is closed, if it is open. *************** *** 3889,3894 **** --- 3941,3947 ---- StartMoving(t); XeOffset2Locations(t, &position, 1, &t->texted.cursor_location, &xy); + t->texted.cursor_position = position; UpdateCursorPosition(t, False, True, True); EndMoving(t); } *** TextEd.h.orig Mon Jan 30 16:05:23 1995 --- TextEd.h Tue Mar 7 12:33:33 1995 *************** *** 199,204 **** --- 199,214 ---- #endif ); + void XeTextChangeMode + ( + #if NeedFunctionPrototypes + Widget, /* TextEd Widget pointer */ + char *, /* Pointer to octets to be inserted (modes) */ + long, /* Number of octets to insert */ + long /* Number of characters to modify after insert */ + #endif + ); + void XeTextReplaceTagged ( #if NeedFunctionPrototypes *** TextImport.c.orig Tue Feb 7 15:57:07 1995 --- TextImport.c Tue Mar 7 16:55:30 1995 *************** *** 2353,2359 **** /* ** SplitSnip ** Split Snip t into two at offset, and return the pointer to the ! ** *NEW* snip, which represents the fisrt part of the split. ** ** *** No checks is made. Function assumes the offset <= length. */ --- 2353,2359 ---- /* ** SplitSnip ** Split Snip t into two at offset, and return the pointer to the ! ** *NEW* snip, which represents the first part of the split. ** ** *** No checks is made. Function assumes the offset <= length. */ *************** *** 2564,2569 **** --- 2564,2698 ---- } return t; } + + static void CopyLockedModes(cx, t) + Context *cx; + Snip *t; + { + unsigned long old_font, new_font; + + old_font = FontSelectInfo(t->mode); + + t->mode.bits &= ~cx->lock.bits; + t->mode.bits |= cx->lock.bits & cx->mode.bits; + if (cx->lock.tag) + t->mode.tag = cx->lock.tag; + if (cx->lock.size_modification) + t->mode.size_modification = cx->mode.size_modification; + new_font = FontSelectInfo(t->mode); + /* + ** If mode change affected the font selection, then we must + ** move the snip content into a matching SnipData chunk. + ** (argh.. this mode change function proves to be nastier than + ** I expected... --msa ) + */ + if (!t->widget && old_font != new_font && t->content.head) + { + int n = t->content.head->bytes * t->length; + + if (cx->used + n > cx->size || + cx->head->character_set != t->content.head->character_set|| + new_font != cx->fontinfo) + { + FlushAppend(cx); + if (cx->size < n) + { + /* Need to reallocate larger head block */ + DerefDataHeader(cx->head); + cx->size = n>HEAD_MIN_SIZE ? n : HEAD_MIN_SIZE; + cx->head = (SnipData *) + XtCalloc(1, XtOffsetOf(SnipData, s[0]) + + cx->size); + cx->head->refs = 1; /* cx ref is counted ! */ + } + cx->fontinfo = new_font; + cx->head->bytes = t->content.head->bytes; + cx->head->font = NULL; + cx->head->character_set=t->content.head->character_set; + cx->first = t; + } + memcpy(&cx->head->s[cx->used], t->data, n); + cx->head->refs += 1; + DerefDataHeader(t->content.head); + t->content.head = cx->head; + t->data = &cx->head->s[cx->used]; + cx->used += n; + } + t->valid = FALSE; /* This snip requires new layout */ + } + + /* + ** _XeTextChangeMode + ** Change the mode of the next 'amount' characters. Only the 'locked' + ** modes defined in the current insert context will be changed. + ** + ** amount > 0, change forward from current point, + ** amount < 0, change backward from current point + */ + void _XeTextChangeMode(context, amount) + XeTextInsertContext context; + long amount; + { + Snip *t; + Snip **h; + int offset, vlength; + Context *cx = (Context *)context; + + if (cx == NULL) + return; + h = cx->last ? &cx->last->next : cx->list; + if (amount > 0) + { + /* + ** Change forward + */ + for (t = *h; t != NULL; t = t->next) + if (IsEditableContent(t->mode.bits)) + { + amount -= (vlength = VirtualLength(t)); + if (amount < 0) + { + offset = amount + vlength; + if (offset > 0 && offset < vlength) + { + t = SplitSnip(cx, t, offset); + CopyLockedModes(cx, t); + } + break; + } + CopyLockedModes(cx, t); + } + } + else if (amount < 0 && *h != NULL) + { + /* + ** Change backward + */ + for (t = *h; ; t = PreviousSnip(t)) + { + if (IsEditableContent(t->mode.bits)) + { + vlength = VirtualLength(t); + amount += vlength; + if (amount == 0) + break; + else if (amount > 0) + { + if (amount < vlength) + { + (void)SplitSnip(cx, t, amount); + CopyLockedModes(cx, t); + } + break; + } + CopyLockedModes(cx, t); + } + else if (t->back == cx->list) + break; + } + } + } + /* ** _XeTextInsertLocation *** TextImport.h.orig Tue Feb 7 13:34:41 1995 --- TextImport.h Tue Mar 7 11:15:48 1995 *************** *** 71,76 **** --- 71,84 ---- #endif ); + void _XeTextChangeMode + ( + #if NeedFunctionPrototypes + XeTextInsertContext, /* Context Pointer */ + long /* Characters to Modify */ + #endif + ); + Snip *_XeTextEndContent ( #if NeedFunctionPrototypes