Коллеги,
предлагаю поправку в TextControllers.StdCtrl.SetNativeProp.
Поправка позволяет применять атрибуты текста к слову (а не только к выделению). Т.о. нажатие ^B делает текущее слово полужирным. Прежняя функциональность сохраняется: если есть выделение, то атрибуты применяются к нему.
Код:
PROCEDURE (c: StdCtrl) SetNativeProp (selection: BOOLEAN; old, p: Properties.Property);
VAR t: TextModels.Model; beg, end: INTEGER; (*▶*)toWord: BOOLEAN;(*◀*)
BEGIN
t := c.text;
IF selection THEN beg := c.selBeg; end := c.selEnd;
(*▶*)IF beg = none THEN toWord := TRUE; c.view.ThisSetter().GetWord(c.carPos, beg, end);
ASSERT(end <= t.Length())
ELSE toWord := FALSE END(*◀*)
ELSE beg := 0; end := t.Length()
END;
IF beg < end THEN
t.Modify(beg, end, old, p);
IF selection (*▶*)& ~toWord(*◀*) THEN c.SetSelection(beg, end) END
ELSIF selection THEN
c.insAttr := TextModels.ModifiedAttr(InsertionAttr(c), p)
END
END SetNativeProp;
Эта поправка выявила небольшой дефект в TextSetters:
Код:
PROCEDURE (s: StdSetter) GetWord (pos: INTEGER; OUT beg, end: INTEGER);
ЕСЛИ (pos = s.text.Length()) & (s.text[последний символ] = 0DX) ТО GetWord возвращает end = s.text.Length() + 1. Т.е. если в конце текста пустая строка, то GetWord возвращает конец слова ЗА концом текста.
Поэтому я, не разбираясь в тонкостях организации StdSetter, предлагаю поправку-заплатку в GetWord:
Код:
UNTIL ~part OR (s.rd.string[0] = 0X) OR (end - beg > wordCutoff);
(*▶*)end := MIN(end, s.text.Length());
ASSERT((0 <= beg) & (beg <= end) & (end <= s.text.Length()), 60)(*◀*)
END GetWord;
Можно еще в документации GetWord явно указать
Код:
Post
end <= s.text.Length()
Но можно и не указывать - это вроде как само собой подразумевается и вытекает из логики работы с текстами: слово не може выходить за границы текста.
В приложении - поправки и модуль, позволяющий выявить указанный дефект, а после внесения поправки - не выявить дефекта.