2
0

Cmds.txt 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. MODULE TextCmds;
  2. (* THIS IS TEXT COPY OF BlackBox Text/Mod/Cmds.odc *)
  3. (* DO NOT EDIT *)
  4. (* could eliminate ReplList/ReplOp and use Models.Begin/EndScript instead (as already done for shifting) *)
  5. (* move ListAlienViews to StdCmds and generalize accordingly? *)
  6. IMPORT
  7. Strings, Ports, Stores, Models, Views, Controllers, Properties, Dialog, Containers,
  8. TextModels, TextMappers, TextRulers, TextSetters, TextViews, TextControllers;
  9. CONST
  10. (* ShiftOp.left *)
  11. left = TRUE; right = FALSE;
  12. (* PreparePat, FindPat *)
  13. leftTerm = 3X; rightTerm = 4X;
  14. (* DoReplace mode *)
  15. replace = 0; replaceAndFind = 1; replaceAll = 2;
  16. (* FindIn first *)
  17. first = TRUE; again = FALSE;
  18. mm = Ports.mm; point = Ports.point; maxPat = 256;
  19. viewcode = TextModels.viewcode;
  20. tab = TextModels.tab; line = TextModels.line; para = TextModels.para;
  21. nbspace = TextModels.nbspace; digitspace = TextModels.digitspace;
  22. hyphen = TextModels.hyphen;
  23. nbhyphen = TextModels.nbhyphen; softhyphen = TextModels.softhyphen;
  24. posKey = "#Text:Position";
  25. searchAliensKey = "#Text:SearchForAlienViews"; (* dormant code option *)
  26. alienTypeKey = "#Text:AlienViewType";
  27. noAliensKey = "#Text:NoAlienViewsFound";
  28. noRulerKey = "#Text:NoRulerSelected";
  29. noMatchKey = "#Text:SelectionDoesNotMatch";
  30. noTargetKey = "#Text:NoTargetFound";
  31. noSelectionKey = "#Text:NoSelectionFound";
  32. noPatternKey = "#Text:PatternNotSpecified";
  33. notFoundKey = "#Text:PatternNotFound"; (* not used *)
  34. replacingKey = "#System:Replacing";
  35. shiftingKey = "#Text:Shifting";
  36. showMarksKey = "#Text:ShowMarks";
  37. hideMarksKey = "#Text:HideMarks";
  38. replaceSelectionKey = "#Text:ReplaceAllInSelection";
  39. replaceAllKey = "#Text:ReplaceAll";
  40. TYPE
  41. FindSpec = RECORD
  42. valid, ignoreCase, wordBeginsWith, wordEndsWith, reverse: BOOLEAN;
  43. start: INTEGER;
  44. find: ARRAY maxPat OF CHAR
  45. END;
  46. ReplList = POINTER TO RECORD
  47. next: ReplList;
  48. beg, end: INTEGER;
  49. buf: TextModels.Model
  50. END;
  51. ReplOp = POINTER TO RECORD (Stores.Operation)
  52. text: TextModels.Model;
  53. list, last: ReplList;
  54. find: FindSpec
  55. END;
  56. VAR
  57. find*: RECORD
  58. find*: ARRAY maxPat OF CHAR;
  59. replace*: ARRAY maxPat OF CHAR;
  60. ignoreCase*, wordBeginsWith*, wordEndsWith*: BOOLEAN;
  61. reverseOrientation*: BOOLEAN
  62. END;
  63. ruler*: RECORD
  64. pageBreaks*: RECORD
  65. notInside*, joinPara*: BOOLEAN
  66. END
  67. END;
  68. PROCEDURE Show (t: TextModels.Model; beg, end: INTEGER);
  69. BEGIN
  70. TextViews.ShowRange(t, beg, end, TextViews.focusOnly);
  71. IF beg = end THEN
  72. TextControllers.SetCaret(t, beg)
  73. ELSE
  74. TextControllers.SetSelection(t, beg, end)
  75. END
  76. END Show;
  77. PROCEDURE NoShow (t: TextModels.Model; pos: INTEGER);
  78. BEGIN
  79. TextControllers.SetSelection(t, pos, pos);
  80. TextControllers.SetCaret(t, pos)
  81. END NoShow;
  82. PROCEDURE Ruler (): TextRulers.Ruler;
  83. VAR r: TextRulers.Ruler;
  84. BEGIN
  85. r := TextRulers.dir.New(NIL);
  86. TextRulers.AddTab(r, 4*mm); TextRulers.AddTab(r, 20*mm);
  87. RETURN r
  88. END Ruler;
  89. (* search & replace *)
  90. PROCEDURE LeftTerminator (ch: CHAR): BOOLEAN;
  91. BEGIN
  92. IF ch < 100X THEN
  93. CASE ch OF
  94. viewcode, tab, line, para, " ",
  95. "(", "[", "{", "=",
  96. hyphen, softhyphen: RETURN TRUE
  97. ELSE RETURN FALSE
  98. END
  99. ELSE RETURN TRUE
  100. END
  101. END LeftTerminator;
  102. PROCEDURE RightTerminator (ch: CHAR): BOOLEAN;
  103. BEGIN
  104. IF ch < 100X THEN
  105. CASE ch OF
  106. 0X, viewcode, tab, line, para, " ",
  107. "!", "(", ")", ",", ".", ":", ";", "?", "[", "]", "{", "}",
  108. hyphen, softhyphen: RETURN TRUE
  109. ELSE RETURN FALSE
  110. END
  111. ELSE RETURN TRUE
  112. END
  113. END RightTerminator;
  114. PROCEDURE PreparePat (spec: FindSpec;
  115. VAR pat: ARRAY OF CHAR; VAR n: INTEGER;
  116. VAR wordBeg, wordEnd: BOOLEAN);
  117. VAR i: INTEGER; ch: CHAR;
  118. BEGIN
  119. i := 0; ch := spec.find[0];
  120. wordBeg := spec.wordBeginsWith & ~LeftTerminator(ch);
  121. IF wordBeg THEN pat[0] := leftTerm; n := 1 ELSE n := 0 END;
  122. WHILE ch # 0X DO
  123. IF ch # softhyphen THEN
  124. IF spec.ignoreCase THEN pat[n] := Strings.Upper(ch) ELSE pat[n] := ch END;
  125. INC(n)
  126. END;
  127. INC(i); ch := spec.find[i]
  128. END;
  129. wordEnd := spec.wordEndsWith & ~RightTerminator(pat[n - 1]);
  130. IF wordEnd THEN pat[n] := rightTerm; INC(n) END
  131. END PreparePat;
  132. PROCEDURE FindPat (t: TextModels.Model; spec: FindSpec; VAR beg, end: INTEGER);
  133. (* post: beg < end => t[beg, end) = spec.find, start <= beg; else beg = end *)
  134. VAR r: TextModels.Reader; start: INTEGER;
  135. i, j, b, e, n: INTEGER; ch0, ch, ch1: CHAR; wordBeg, wordEnd, icase: BOOLEAN;
  136. pat, ref: ARRAY maxPat OF CHAR; (* ref [b..e) is readback buffer *)
  137. pos0, pos1, absStart: INTEGER;
  138. orientation: INTEGER;
  139. BEGIN
  140. IF spec.reverse THEN
  141. orientation := -1; absStart := t.Length();
  142. PreparePat(spec, ref, n, wordEnd, wordBeg);
  143. i := n; j := 0; REPEAT DEC(i); pat[j] := ref[i]; INC(j) UNTIL i = 0 (* Just reverse the pattern... *)
  144. ELSE
  145. orientation := 1; absStart := 0;
  146. PreparePat(spec, pat, n, wordBeg, wordEnd)
  147. END;
  148. start := spec.start; icase := spec.ignoreCase;
  149. r := t.NewReader(NIL); i := 0;
  150. IF wordBeg THEN
  151. IF start # absStart THEN
  152. DEC(start, orientation)
  153. ELSE
  154. r.SetPos(absStart);
  155. IF spec.reverse THEN r.ReadPrevChar(ch) ELSE r.ReadChar(ch) END;
  156. IF ~LeftTerminator(ch) THEN i := 1 END
  157. END
  158. END;
  159. r.SetPos(start); IF spec.reverse THEN r.ReadPrevChar(ch) ELSE r.ReadChar(ch) END;
  160. pos0 := start; pos1 := start;
  161. IF icase THEN ch := Strings.Upper(ch) END;
  162. ref[0] := ch; ch0 := ch; j := 0; b := 0; e := 1;
  163. WHILE ~r.eot & (i < n) DO
  164. ch1 := pat[i];
  165. IF (ch1 = ch)
  166. OR (ch1 = leftTerm) & LeftTerminator(ch)
  167. OR (ch1 = rightTerm) & RightTerminator(ch) THEN
  168. INC(i); j := (j + 1) MOD maxPat
  169. ELSIF ch = softhyphen THEN
  170. j := (j + 1) MOD maxPat
  171. ELSE
  172. i := 0; INC(pos0, orientation); b := (b + 1) MOD maxPat; j := b
  173. END;
  174. IF j # e THEN
  175. ch := ref[j]
  176. ELSE
  177. INC(pos1, orientation);
  178. IF spec.reverse THEN r.ReadPrevChar(ch) ELSE r.ReadChar(ch) END;
  179. IF icase THEN ch := Strings.Upper(ch) END;
  180. ref[j] := ch; e := (e + 1) MOD maxPat
  181. END
  182. END;
  183. IF wordEnd & ~((i + 1 = n) & r.eot) THEN DEC(pos1, orientation) END;
  184. IF (n > 0) & ((i = n) OR wordEnd & (i + 1 = n) & r.eot) THEN
  185. IF wordBeg & ((pos0 # absStart) OR LeftTerminator(ch0)) THEN INC(pos0, orientation) END
  186. ELSE
  187. pos0 := pos1
  188. END;
  189. IF spec.reverse THEN
  190. beg := pos1; end := pos0
  191. ELSE
  192. beg := pos0; end := pos1
  193. END
  194. END FindPat;
  195. PROCEDURE OverrideSpecWithOption (VAR spec: FindSpec; option: ARRAY OF CHAR);
  196. VAR i: INTEGER; choice: BOOLEAN; ch: CHAR;
  197. BEGIN
  198. choice := TRUE; i := 0; ch := option[i];
  199. WHILE ch # 0X DO
  200. CASE option[i] OF
  201. '~': choice := ~choice
  202. | 'I', 'i': spec.ignoreCase := choice; choice := TRUE
  203. | 'B', 'b': spec.wordBeginsWith := choice; choice := TRUE
  204. | 'E', 'e': spec.wordEndsWith := choice; choice := TRUE
  205. | 'R', 'r': spec.reverse := choice; choice := TRUE
  206. ELSE choice := TRUE
  207. END;
  208. INC(i); ch := option[i]
  209. END
  210. END OverrideSpecWithOption;
  211. PROCEDURE SetSpec (VAR spec: FindSpec; pos0, pos1: INTEGER; option: ARRAY OF CHAR);
  212. BEGIN
  213. ASSERT(find.find # "", 20);
  214. spec.valid := TRUE;
  215. spec.ignoreCase := find.ignoreCase;
  216. spec.wordBeginsWith := find.wordBeginsWith;
  217. spec.wordEndsWith := find.wordEndsWith;
  218. spec.reverse := find.reverseOrientation;
  219. OverrideSpecWithOption(spec, option);
  220. IF spec.reverse THEN spec.start := pos1
  221. ELSE spec.start := pos0
  222. END;
  223. spec.find := find.find$
  224. END SetSpec;
  225. PROCEDURE SetFindSpec (c: TextControllers.Controller; first: BOOLEAN; option: ARRAY OF CHAR;
  226. VAR spec: FindSpec
  227. );
  228. VAR (*start,*) pos0, pos1, beg, end: INTEGER;
  229. BEGIN
  230. IF first THEN pos0 := 0; pos1 := pos0
  231. ELSIF c.HasCaret() THEN pos0 := c.CaretPos(); pos1 := pos0
  232. ELSIF c.HasSelection() THEN c.GetSelection(beg, end); pos0 := beg + 1; pos1 := end - 1
  233. ELSE pos0 := 0; pos1 := pos0
  234. END;
  235. SetSpec(spec, pos0, pos1, option);
  236. IF spec.reverse THEN
  237. IF spec.start = 0 THEN spec.start := c.text.Length() END
  238. ELSE
  239. IF spec.start = c.text.Length() THEN spec.start := 0 END
  240. END
  241. END SetFindSpec;
  242. PROCEDURE ReplBuf (target: TextModels.Model; pos: INTEGER): TextModels.Model;
  243. VAR buf: TextModels.Model; attr: TextModels.Attributes; rd: TextModels.Reader;
  244. out: TextModels.Writer; i: INTEGER;
  245. BEGIN
  246. rd := target.NewReader(NIL); rd.SetPos(pos); rd.ReadRun(attr);
  247. buf := TextModels.CloneOf(target); out := buf.NewWriter(NIL); out.SetPos(0);
  248. IF attr # NIL THEN out.SetAttr(attr) END;
  249. i := 0; WHILE find.replace[i] # 0X DO out.WriteChar(find.replace[i]); INC(i) END;
  250. RETURN buf
  251. END ReplBuf;
  252. (* operations *)
  253. PROCEDURE (op: ReplOp) Do;
  254. VAR u, v: ReplList; text, save: TextModels.Model; beg, end, delta, len: INTEGER;
  255. BEGIN
  256. text := op.text;
  257. u := op.list; v := NIL; delta := 0;
  258. WHILE u # NIL DO
  259. INC(u.beg, delta); INC(u.end, delta);
  260. IF u.end > u.beg THEN
  261. save := TextModels.CloneOf(text); save.Insert(0, text, u.beg, u.end);
  262. DEC(delta, u.end - u.beg)
  263. ELSE
  264. save := NIL
  265. END;
  266. IF u.buf # NIL THEN
  267. len := u.buf.Length();
  268. text.Insert(u.beg, u.buf, 0, len);
  269. u.end := u.beg + len;
  270. INC(delta, len)
  271. ELSE
  272. u.end := u.beg
  273. END;
  274. u.buf := save;
  275. v := u; u := u.next
  276. END;
  277. IF op.find.valid THEN
  278. FindPat(text, op.find, beg, end); op.find.valid := FALSE;
  279. IF beg = end THEN Dialog.Beep END
  280. ELSIF v # NIL THEN
  281. beg := v.beg; end := v.end
  282. ELSE
  283. beg := 0; end := 0
  284. END;
  285. IF end > beg THEN Show(text, beg, end) ELSE NoShow(text, beg) END
  286. END Do;
  287. PROCEDURE AddRepl (op: ReplOp; beg, end: INTEGER; reverse: BOOLEAN);
  288. VAR u: ReplList;
  289. BEGIN
  290. NEW(u); u.beg := beg; u.end := end; u.buf := ReplBuf(op.text, beg);
  291. IF reverse THEN (* append *)
  292. u.next := op.list; op.list := u
  293. ELSE (* prepend *)
  294. IF op.list = NIL THEN op.list := u ELSE op.last.next := u END;
  295. op.last := u
  296. END
  297. END AddRepl;
  298. PROCEDURE DoReplaceThis (
  299. t: TextModels.Model; mode: INTEGER;
  300. firstBeg, firstEnd: INTEGER;
  301. rngBeg, rngEnd: INTEGER;
  302. option: ARRAY OF CHAR
  303. );
  304. VAR op: ReplOp; spec: FindSpec; beg, end, len: INTEGER;
  305. BEGIN
  306. NEW(op); op.text := t; op.list := NIL;
  307. beg := firstBeg; end := firstEnd;
  308. IF mode IN {replace, replaceAndFind} THEN
  309. AddRepl(op, firstBeg, firstEnd, spec.reverse)
  310. END;
  311. IF mode = replaceAndFind THEN
  312. SetSpec(op.find, firstBeg + (* LEN(find.replace$) *) ReplBuf(t, 0).Length(), firstBeg, option)
  313. ELSE
  314. op.find.valid := FALSE
  315. END;
  316. IF mode = replaceAll THEN
  317. len := LEN(find.find$);
  318. SetSpec(spec, 0, t.Length(), option);
  319. WHILE (rngBeg <= beg) & (beg < end) & (end <= rngEnd) DO
  320. AddRepl(op, beg, end, spec.reverse);
  321. IF spec.reverse THEN spec.start := beg ELSE spec.start := beg + len END;
  322. FindPat(t, spec, beg, end)
  323. END
  324. END;
  325. Models.Do(t, replacingKey, op)
  326. END DoReplaceThis;
  327. PROCEDURE DoReplace (c: TextControllers.Controller; mode: INTEGER; option: ARRAY OF CHAR);
  328. VAR t: TextModels.Model; spec: FindSpec;
  329. selBeg, selEnd, beg, end, len0: INTEGER; hasSel0: BOOLEAN;
  330. BEGIN
  331. IF c # NIL THEN
  332. t := c.text; len0 := t.Length(); hasSel0 := c.HasSelection();
  333. IF hasSel0 THEN
  334. c.GetSelection(selBeg, selEnd);
  335. IF selEnd < len0 THEN
  336. SetSpec(spec, selBeg, selEnd + 1, option)
  337. ELSE SetSpec(spec, selBeg, selEnd, option)
  338. END
  339. ELSE
  340. selBeg := 0; selEnd := len0;
  341. SetFindSpec(c, (* again *) mode = replaceAll, option, spec)
  342. END;
  343. FindPat(t, spec, beg, end);
  344. IF mode = replaceAll THEN
  345. IF (selBeg <= beg) & (beg < end) & (end <= selEnd) THEN
  346. DoReplaceThis(t, mode, beg, end, selBeg, selEnd, option);
  347. IF hasSel0 THEN Show(c.text, selBeg, selEnd + t.Length() - len0) END
  348. ELSE NoShow(c.text, 0); Dialog.Beep
  349. END
  350. ELSIF hasSel0 THEN
  351. IF (beg = selBeg) & (end = selEnd) THEN
  352. DoReplaceThis(t, mode, selBeg, selEnd, 0, len0, option)
  353. ELSE Dialog.ShowParamMsg(noMatchKey, spec.find, "", "")
  354. END
  355. ELSE Dialog.ShowMsg(noSelectionKey)
  356. END
  357. ELSE Dialog.ShowMsg(noTargetKey)
  358. END
  359. END DoReplace;
  360. PROCEDURE DoShift (c: TextControllers.Controller; left: BOOLEAN);
  361. VAR script: Stores.Operation;
  362. t: TextModels.Model; st: TextSetters.Setter;
  363. rd: TextModels.Reader; wr: TextModels.Writer;
  364. box: TextSetters.LineBox; beg, pos, end: INTEGER; ch: CHAR;
  365. BEGIN
  366. IF (c # NIL) & (c.HasSelection() OR c.HasCaret()) THEN
  367. t := c.text;
  368. IF c.HasSelection() THEN c.GetSelection(beg, end) ELSE beg := c.CaretPos(); end := beg END;
  369. st := c.view.ThisSetter(); beg := st.ThisSequence(beg); pos := beg;
  370. rd := t.NewReader(NIL); rd.SetPos(pos);
  371. IF ~left THEN wr := t.NewWriter(NIL) END;
  372. Models.BeginScript(t, shiftingKey, script);
  373. REPEAT
  374. rd.ReadChar(ch);
  375. IF rd.view # NIL THEN
  376. st.GetLine(pos, box);
  377. IF box.rbox THEN ch := para END
  378. END;
  379. IF left & ((ch = tab) OR (ch = " ") OR (ch = digitspace) OR (ch = nbspace)) THEN
  380. t.Delete(pos, pos + 1); rd.SetPos(pos); DEC(end)
  381. ELSIF ~left & (ch # line) & (ch # para) THEN
  382. wr.SetPos(pos);
  383. IF (ch = " ") OR (ch = digitspace) OR (ch = nbspace) THEN
  384. wr.WriteChar(ch)
  385. ELSE wr.WriteChar(tab)
  386. END;
  387. INC(pos); INC(end)
  388. ELSE INC(pos)
  389. END;
  390. WHILE ~rd.eot & (ch # line) & (ch # para) DO
  391. INC(pos); rd.ReadChar(ch)
  392. END
  393. UNTIL rd.eot OR (pos >= end);
  394. Models.EndScript(t, script);
  395. IF end > beg THEN TextControllers.SetSelection(t, beg, end) END
  396. END
  397. END DoShift;
  398. (** commands **)
  399. PROCEDURE ListAlienViews*;
  400. VAR t: TextModels.Model; v: TextViews.View; wr: TextMappers.Formatter;
  401. rd: TextModels.Reader; view: Views.View;
  402. type: Stores.TypeName; none: BOOLEAN;
  403. BEGIN
  404. t := TextViews.FocusText();
  405. IF t # NIL THEN
  406. wr.ConnectTo(TextModels.dir.New());
  407. rd := t.NewReader(NIL); rd.ReadView(view); none := TRUE;
  408. WHILE view # NIL DO
  409. IF view IS Views.Alien THEN
  410. IF none THEN
  411. wr.WriteTab; wr.WriteMsg(posKey);
  412. wr.WriteTab; wr.WriteMsg(alienTypeKey); wr.WriteLn
  413. END;
  414. none := FALSE;
  415. type := view(Views.Alien).store.path[0]$;
  416. wr.WriteTab;
  417. wr.WriteIntForm(rd.Pos() - 1,
  418. TextMappers.decimal, 5, nbspace, TextMappers.hideBase);
  419. wr.WriteTab; wr.WriteString(type); wr.WriteLn
  420. END;
  421. rd.ReadView(view)
  422. END;
  423. IF none THEN wr.WriteString(noAliensKey); wr.WriteLn END;
  424. v := TextViews.dir.New(wr.rider.Base());
  425. v.SetDefaults(Ruler(), TextViews.dir.defAttr);
  426. Views.OpenView(v)
  427. END
  428. END ListAlienViews;
  429. PROCEDURE ToggleMarksGuard* (VAR par: Dialog.Par);
  430. VAR v: TextViews.View;
  431. BEGIN
  432. v := TextViews.Focus();
  433. IF (v # NIL) & v.HidesMarks() THEN par.label := showMarksKey
  434. ELSE par.label := hideMarksKey
  435. END
  436. END ToggleMarksGuard;
  437. PROCEDURE ToggleMarks*;
  438. VAR v: TextViews.View;
  439. BEGIN
  440. v := TextViews.Focus();
  441. IF v # NIL THEN v.DisplayMarks(~v.HidesMarks()) END
  442. END ToggleMarks;
  443. PROCEDURE ShowMarks*;
  444. VAR v: TextViews.View;
  445. BEGIN
  446. v := TextViews.Focus();
  447. IF (v # NIL) & v.HidesMarks() THEN v.DisplayMarks(TextViews.show) END
  448. END ShowMarks;
  449. PROCEDURE HideMarks*;
  450. VAR v: TextViews.View;
  451. BEGIN
  452. v := TextViews.Focus();
  453. IF (v # NIL) & ~v.HidesMarks() THEN v.DisplayMarks(TextViews.hide) END
  454. END HideMarks;
  455. PROCEDURE MakeDefaultRulerGuard* (VAR par: Dialog.Par);
  456. VAR c: TextControllers.Controller; v: Views.View;
  457. BEGIN
  458. c := TextControllers.Focus();
  459. IF c # NIL THEN
  460. v := c.Singleton();
  461. IF (v = NIL) OR ~(v IS TextRulers.Ruler) THEN par.disabled := TRUE END
  462. ELSE par.disabled := TRUE
  463. END
  464. END MakeDefaultRulerGuard;
  465. PROCEDURE MakeDefaultRuler*;
  466. VAR c: TextControllers.Controller; rd: TextModels.Reader;
  467. r: TextRulers.Ruler; a: TextModels.Attributes;
  468. beg, end: INTEGER;
  469. BEGIN
  470. c := TextControllers.Focus();
  471. IF c # NIL THEN
  472. IF c.HasSelection() THEN
  473. c.GetSelection(beg, end);
  474. rd := c.text.NewReader(NIL); rd.SetPos(beg); rd.Read;
  475. IF (rd.view # NIL) & (rd.view IS TextRulers.Ruler) THEN
  476. c.view.PollDefaults(r, a);
  477. c.view.SetDefaults(rd.view(TextRulers.Ruler), a)
  478. ELSE Dialog.ShowMsg(noRulerKey)
  479. END
  480. ELSE Dialog.ShowMsg(noSelectionKey)
  481. END
  482. ELSE Dialog.ShowMsg(noTargetKey)
  483. END
  484. END MakeDefaultRuler;
  485. PROCEDURE MakeDefaultAttributes*;
  486. VAR c: TextControllers.Controller; rd: TextModels.Reader;
  487. r: TextRulers.Ruler; a: TextModels.Attributes;
  488. beg, end: INTEGER;
  489. BEGIN
  490. c := TextControllers.Focus();
  491. IF c # NIL THEN
  492. IF c.HasSelection() THEN
  493. c.GetSelection(beg, end);
  494. rd := c.text.NewReader(NIL); rd.SetPos(beg); rd.Read;
  495. c.view.PollDefaults(r, a);
  496. c.view.SetDefaults(r, rd.attr)
  497. ELSE Dialog.ShowMsg(noSelectionKey)
  498. END
  499. ELSE Dialog.ShowMsg(noTargetKey)
  500. END
  501. END MakeDefaultAttributes;
  502. PROCEDURE ShiftLeft*;
  503. BEGIN
  504. DoShift(TextControllers.Focus(), left)
  505. END ShiftLeft;
  506. PROCEDURE ShiftRight*;
  507. BEGIN
  508. DoShift(TextControllers.Focus(), right)
  509. END ShiftRight;
  510. PROCEDURE Subscript*;
  511. VAR q, p0: Properties.Property; p: TextModels.Prop;
  512. BEGIN
  513. Properties.CollectProp(q);
  514. p0 := q; WHILE (p0 # NIL) & ~(p0 IS TextModels.Prop) DO p0 := p0.next END;
  515. NEW(p); p.valid := {TextModels.offset};
  516. IF (p0 # NIL) & (TextModels.offset IN p0.valid) THEN
  517. p.offset := p0(TextModels.Prop).offset - point
  518. ELSE p.offset := -point
  519. END;
  520. Properties.EmitProp(NIL, p)
  521. END Subscript;
  522. PROCEDURE Superscript*;
  523. VAR q, p0: Properties.Property; p: TextModels.Prop;
  524. BEGIN
  525. Properties.CollectProp(q);
  526. p0 := q; WHILE (p0 # NIL) & ~(p0 IS TextModels.Prop) DO p0 := p0.next END;
  527. NEW(p); p.valid := {TextModels.offset};
  528. IF (p0 # NIL) & (TextModels.offset IN p0.valid) THEN
  529. p.offset := p0(TextModels.Prop).offset + point
  530. ELSE p.offset := point
  531. END;
  532. Properties.EmitProp(NIL, p)
  533. END Superscript;
  534. PROCEDURE ForceToNewLine (c: TextControllers.Controller);
  535. VAR st: TextSetters.Setter; pos, start: INTEGER; msg: Controllers.EditMsg;
  536. BEGIN
  537. IF c.HasCaret() THEN
  538. pos := c.CaretPos();
  539. st := c.view.ThisSetter(); start := st.ThisLine(pos);
  540. IF pos # start THEN
  541. msg.op := Controllers.pasteChar; msg.char := line;
  542. Controllers.Forward(msg)
  543. END
  544. END
  545. END ForceToNewLine;
  546. PROCEDURE InsertParagraph*;
  547. VAR c: TextControllers.Controller; script: Stores.Operation; msg: Controllers.EditMsg;
  548. BEGIN
  549. c := TextControllers.Focus();
  550. IF c # NIL THEN
  551. Models.BeginScript(c.text, "#Text:InsertParagraph", script);
  552. ForceToNewLine(c);
  553. msg.op := Controllers.pasteChar; msg.char := para;
  554. Controllers.Forward(msg);
  555. Models.EndScript(c.text, script)
  556. END
  557. END InsertParagraph;
  558. PROCEDURE InsertRuler*;
  559. VAR c: TextControllers.Controller; script: Stores.Operation;
  560. rd: TextModels.Reader; r: TextRulers.Ruler;
  561. pos, end: INTEGER;
  562. BEGIN
  563. c := TextControllers.Focus();
  564. IF c # NIL THEN
  565. r := NIL;
  566. IF c.HasSelection() THEN
  567. c.GetSelection(pos, end);
  568. rd := c.text.NewReader(NIL); rd.SetPos(pos); rd.Read;
  569. IF (rd.view # NIL) & (rd.view IS TextRulers.Ruler) THEN
  570. r := rd.view(TextRulers.Ruler)
  571. END
  572. ELSE pos := c.CaretPos()
  573. END;
  574. IF r = NIL THEN r := TextViews.ThisRuler(c.view, pos) END;
  575. r := TextRulers.CopyOf(r, Views.deep);
  576. Models.BeginScript(c.text, "#Text:InsertRuler", script);
  577. ForceToNewLine(c);
  578. c.view.DisplayMarks(TextViews.show);
  579. Controllers.PasteView(r, Views.undefined, Views.undefined, FALSE);
  580. Models.EndScript(c.text, script)
  581. END
  582. END InsertRuler;
  583. PROCEDURE InsertSoftHyphen*;
  584. VAR msg: Controllers.EditMsg;
  585. BEGIN
  586. msg.op := Controllers.pasteChar; msg.char := softhyphen;
  587. Controllers.Forward(msg)
  588. END InsertSoftHyphen;
  589. PROCEDURE InsertNBHyphen*;
  590. VAR msg: Controllers.EditMsg;
  591. BEGIN
  592. msg.op := Controllers.pasteChar; msg.char := nbhyphen;
  593. Controllers.Forward(msg)
  594. END InsertNBHyphen;
  595. PROCEDURE InsertNBSpace*;
  596. VAR msg: Controllers.EditMsg;
  597. BEGIN
  598. msg.op := Controllers.pasteChar; msg.char := nbspace;
  599. Controllers.Forward(msg)
  600. END InsertNBSpace;
  601. PROCEDURE InsertDigitSpace*;
  602. VAR msg: Controllers.EditMsg;
  603. BEGIN
  604. msg.op := Controllers.pasteChar; msg.char := digitspace;
  605. Controllers.Forward(msg)
  606. END InsertDigitSpace;
  607. PROCEDURE GetFindPattern (c: TextControllers.Controller);
  608. VAR r: TextModels.Reader; beg, end: INTEGER; i: INTEGER; ch: CHAR;
  609. new: ARRAY maxPat OF CHAR;
  610. BEGIN
  611. IF (c # NIL) & c.HasSelection() THEN
  612. c.GetSelection(beg, end);
  613. r := c.text.NewReader(NIL); r.SetPos(beg); r.ReadChar(ch); i := 0;
  614. WHILE (r.Pos() <= end) & (i < maxPat - 1) DO
  615. new[i] := ch; INC(i); r.ReadChar(ch)
  616. END;
  617. new[i] := 0X;
  618. IF (new # "") & (new # find.find) THEN
  619. find.find := new$;
  620. find.ignoreCase := FALSE;
  621. find.wordBeginsWith := FALSE; find.wordEndsWith := FALSE;
  622. Dialog.Update(find)
  623. END
  624. END
  625. END GetFindPattern;
  626. PROCEDURE FindIn (c: TextControllers.Controller; first: BOOLEAN; option: ARRAY OF CHAR);
  627. VAR spec: FindSpec; beg, end: INTEGER;
  628. BEGIN
  629. IF c # NIL THEN
  630. IF find.find # "" THEN
  631. SetFindSpec(c, first, option, spec);
  632. FindPat(c.text, spec, beg, end);
  633. IF end > beg THEN Show(c.text, beg, end) ELSE NoShow(c.text, 0); Dialog.Beep END
  634. ELSE Dialog.ShowMsg(noPatternKey)
  635. END
  636. ELSE Dialog.ShowMsg(noTargetKey)
  637. END
  638. END FindIn;
  639. PROCEDURE FindGuard* (VAR par: Dialog.Par);
  640. VAR c: TextControllers.Controller;
  641. BEGIN
  642. c := TextControllers.Focus();
  643. IF (c = NIL) OR (find.find = "") THEN par.disabled := TRUE END
  644. END FindGuard;
  645. PROCEDURE FindFirst* (option: ARRAY OF CHAR);
  646. BEGIN
  647. FindIn(TextControllers.Focus(), first, option)
  648. END FindFirst;
  649. PROCEDURE FindAgainGuard* (VAR par: Dialog.Par);
  650. VAR c: TextControllers.Controller;
  651. BEGIN
  652. c := TextControllers.Focus();
  653. IF (c = NIL) OR (~c.HasSelection() & (find.find = "")) THEN par.disabled := TRUE END
  654. END FindAgainGuard;
  655. PROCEDURE FindAgain* (option: ARRAY OF CHAR);
  656. BEGIN
  657. FindIn(TextControllers.Focus(), again, option)
  658. END FindAgain;
  659. PROCEDURE ReplaceGuard* (VAR par: Dialog.Par);
  660. VAR c: TextControllers.Controller;
  661. BEGIN
  662. c := TextControllers.Focus();
  663. IF (c = NIL) OR (Containers.noCaret IN c.opts) OR ~c.HasSelection() OR (find.find = "") THEN
  664. par.disabled := TRUE
  665. END
  666. END ReplaceGuard;
  667. PROCEDURE Replace* (option: ARRAY OF CHAR);
  668. BEGIN
  669. DoReplace(TextControllers.Focus(), replace, option)
  670. END Replace;
  671. PROCEDURE ReplaceAndFindNext* (option: ARRAY OF CHAR);
  672. BEGIN
  673. DoReplace(TextControllers.Focus(), replaceAndFind, option)
  674. END ReplaceAndFindNext;
  675. PROCEDURE ReplaceAllGuard* (VAR par: Dialog.Par);
  676. VAR c: TextControllers.Controller;
  677. BEGIN
  678. c := TextControllers.Focus();
  679. IF (c = NIL) OR (Containers.noCaret IN c.opts) OR (find.find = "") THEN
  680. par.disabled := TRUE
  681. ELSE
  682. IF c.HasSelection() THEN par.label := replaceSelectionKey ELSE par.label := replaceAllKey END
  683. END
  684. END ReplaceAllGuard;
  685. PROCEDURE ReplaceAll* (option: ARRAY OF CHAR);
  686. BEGIN
  687. DoReplace(TextControllers.Focus(), replaceAll, option)
  688. END ReplaceAll;
  689. PROCEDURE SetNormalOrientation*;
  690. BEGIN
  691. find.reverseOrientation := FALSE;
  692. Dialog.Update(find)
  693. END SetNormalOrientation;
  694. PROCEDURE SetReverseOrientation*;
  695. BEGIN
  696. find.reverseOrientation := TRUE;
  697. Dialog.Update(find)
  698. END SetReverseOrientation;
  699. PROCEDURE InitFindDialog*;
  700. BEGIN
  701. GetFindPattern(TextControllers.Focus())
  702. END InitFindDialog;
  703. (** ruler dialog **)
  704. PROCEDURE InitRulerDialog*;
  705. VAR v: Views.View; ra: TextRulers.Attributes;
  706. BEGIN
  707. v := Controllers.FocusView();
  708. IF v # NIL THEN
  709. WITH v: TextRulers.Ruler DO
  710. ra := v.style.attr;
  711. ruler.pageBreaks.notInside := TextRulers.noBreakInside IN ra.opts;
  712. ruler.pageBreaks.joinPara := TextRulers.parJoin IN ra.opts
  713. ELSE
  714. END
  715. END
  716. END InitRulerDialog;
  717. PROCEDURE SetRuler*;
  718. VAR v: Views.View; p: TextRulers.Prop;
  719. BEGIN
  720. v := Controllers.FocusView();
  721. IF v # NIL THEN
  722. WITH v: TextRulers.Ruler DO
  723. NEW(p); p.valid := {TextRulers.opts};
  724. p.opts.mask := {TextRulers.noBreakInside, TextRulers.parJoin};
  725. p.opts.val := {};
  726. IF ruler.pageBreaks.notInside THEN INCL(p.opts.val, TextRulers.noBreakInside) END;
  727. IF ruler.pageBreaks.joinPara THEN INCL(p.opts.val, TextRulers.parJoin) END;
  728. Properties.EmitProp(NIL, p)
  729. ELSE
  730. END
  731. END
  732. END SetRuler;
  733. (** standard text-related guards **)
  734. PROCEDURE FocusGuard* (VAR par: Dialog.Par);
  735. (** in non-TextView menus; otherwise implied by menu type **)
  736. BEGIN
  737. IF TextViews.Focus() = NIL THEN par.disabled := TRUE END
  738. END FocusGuard;
  739. PROCEDURE EditGuard* (VAR par: Dialog.Par);
  740. (** in non-TextView menus; otherwise use "StdCmds.EditGuard" **)
  741. VAR c: TextControllers.Controller;
  742. BEGIN
  743. c := TextControllers.Focus();
  744. IF (c = NIL) OR (Containers.noCaret IN c.opts) THEN par.disabled := TRUE END
  745. END EditGuard;
  746. PROCEDURE SelectionGuard* (VAR par: Dialog.Par);
  747. (** in non-TextView menus; otherwise use "StdCmds.SelectionGuard" **)
  748. VAR c: TextControllers.Controller;
  749. BEGIN
  750. c := TextControllers.Focus();
  751. IF (c = NIL) OR ~c.HasSelection() THEN par.disabled := TRUE END
  752. END SelectionGuard;
  753. PROCEDURE EditSelectionGuard* (VAR par: Dialog.Par);
  754. (** in non-TextView menus; otherwise use "StdCmds.SelectionGuard" **)
  755. VAR c: TextControllers.Controller;
  756. BEGIN
  757. c := TextControllers.Focus();
  758. IF (c = NIL) OR (Containers.noCaret IN c.opts) OR ~c.HasSelection() THEN par.disabled := TRUE END
  759. END EditSelectionGuard;
  760. PROCEDURE SingletonGuard* (VAR par: Dialog.Par);
  761. (** in non-TextView menus; otherwise use "StdCmds.SingletonGuard" **)
  762. VAR c: TextControllers.Controller;
  763. BEGIN
  764. c := TextControllers.Focus();
  765. IF (c = NIL) OR (c.Singleton() = NIL) THEN par.disabled := TRUE END
  766. END SingletonGuard;
  767. END TextCmds.