PageRenderTime 54ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/source/src/Edit/Modify/edit_table.cpp

http://itexmacs.googlecode.com/
C++ | 1431 lines | 1260 code | 131 blank | 40 comment | 488 complexity | a611bb89633455af427a427657a1280c MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.0
  1. /******************************************************************************
  2. * MODULE : edit_table.cpp
  3. * DESCRIPTION: modify tables
  4. * COPYRIGHT : (C) 1999 Joris van der Hoeven
  5. *******************************************************************************
  6. * This software falls under the GNU general public license version 3 or later.
  7. * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
  8. * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
  9. ******************************************************************************/
  10. #include "edit_table.hpp"
  11. /******************************************************************************
  12. * Constructors and destructors
  13. ******************************************************************************/
  14. edit_table_rep::edit_table_rep (): cell_mode ("cell") {}
  15. edit_table_rep::~edit_table_rep () {}
  16. /******************************************************************************
  17. * Elementary subroutines for table manipulation
  18. ******************************************************************************/
  19. static tree
  20. empty_cell () {
  21. return "";
  22. }
  23. static bool
  24. is_empty_cell (tree t) {
  25. return t == "" || t == tree (DOCUMENT, "");
  26. }
  27. static tree
  28. empty_row (int nr_cols) {
  29. int i;
  30. tree R (ROW, nr_cols);
  31. for (i=0; i<nr_cols; i++)
  32. R[i]= tree (CELL, empty_cell ());
  33. return R;
  34. }
  35. static tree
  36. empty_table (int nr_rows, int nr_cols) {
  37. int i;
  38. tree T (TABLE, nr_rows);
  39. for (i=0; i<nr_rows; i++)
  40. T[i]= empty_row (nr_cols);
  41. return T;
  42. }
  43. static void
  44. table_get_extents (tree T, int& nr_rows, int& nr_cols) {
  45. while (is_func (T, TFORMAT)) T= T[N(T)-1];
  46. nr_rows= N(T);
  47. T= T[0];
  48. while (is_func (T, TFORMAT)) T= T[N(T)-1];
  49. nr_cols= N(T);
  50. }
  51. static void
  52. table_set (tree& T, int row, int col, tree t) {
  53. tree* ptr= &T;
  54. while (is_func (*ptr, TFORMAT)) ptr= & ((*ptr) [N(*ptr)-1]);
  55. ptr= & ((*ptr) [row]);
  56. while (is_func (*ptr, TFORMAT)) ptr= & ((*ptr) [N(*ptr)-1]);
  57. ptr= & ((*ptr) [col]);
  58. while (is_func (*ptr, TFORMAT)) ptr= & ((*ptr) [N(*ptr)-1]);
  59. if (is_func (*ptr, CELL, 1)) ptr= & ((*ptr) [0]);
  60. *ptr= t;
  61. }
  62. static tree
  63. table_get (tree T, int row, int col) {
  64. while (is_func (T, TFORMAT)) T= T [N(T)-1];
  65. T= T [row];
  66. while (is_func (T, TFORMAT)) T= T [N(T)-1];
  67. T= T [col];
  68. while (is_func (T, TFORMAT)) T= T [N(T)-1];
  69. if (is_func (T, CELL, 1)) T= T [0];
  70. return T;
  71. }
  72. /******************************************************************************
  73. * Searching the format, table, rows and cells
  74. ******************************************************************************/
  75. path
  76. edit_table_rep::search_format () {
  77. path p= search_table ();
  78. return search_format (p);
  79. }
  80. path
  81. edit_table_rep::search_format (path p) {
  82. if (!(rp < p)) return path ();
  83. if (is_func (subtree (et, p), TFORMAT)) return p;
  84. if (is_func (subtree (et, path_up (p)), TFORMAT)) return path_up (p);
  85. return p;
  86. }
  87. path
  88. edit_table_rep::search_format (int& row, int& col) {
  89. path p= search_table (row, col);
  90. if (is_nil (p)) return p;
  91. if (is_func (subtree (et, p), TFORMAT)) return p;
  92. if (is_func (subtree (et, path_up (p)), TFORMAT)) return path_up (p);
  93. insert_node (p * 0, TFORMAT);
  94. return p;
  95. }
  96. path
  97. edit_table_rep::search_table () {
  98. return search_upwards (TABLE);
  99. }
  100. path
  101. edit_table_rep::search_table (path fp) {
  102. tree st= subtree (et, fp);
  103. if (is_func (st, TABLE)) return fp;
  104. if (is_func (st, TFORMAT)) return search_table (fp * (N(st)-1));
  105. return path ();
  106. }
  107. path
  108. edit_table_rep::search_table (int& row, int& col) {
  109. row= col= 0;
  110. path p= search_table ();
  111. if (is_nil (p)) return p;
  112. path q= p, r= tail (tp, N(p));
  113. if (N(r) <= 1) return path ();
  114. row= r->item;
  115. while (true) {
  116. if (is_nil (r)) return r;
  117. q= q * r->item;
  118. r= r->next;
  119. if (is_func (subtree (et, q), ROW)) break;
  120. }
  121. if (N(r) <= 1) return path ();
  122. col= r->item;
  123. while (true) {
  124. if (is_nil (r)) return r;
  125. q= q * r->item;
  126. r= r->next;
  127. if (!is_func (subtree (et, q), TFORMAT)) break;
  128. }
  129. return p;
  130. }
  131. path
  132. edit_table_rep::search_row (path fp, int row) {
  133. fp= search_table (fp) * row;
  134. tree st= subtree (et, fp);
  135. if (!is_func (st, ROW))
  136. return search_row (fp, N(st)-1);
  137. return fp;
  138. }
  139. path
  140. edit_table_rep::search_cell (path p, int col) {
  141. p= p * col;
  142. tree st= subtree (et, p);
  143. if (is_func (st, TFORMAT))
  144. return search_cell (p, N(st)-1);
  145. if (is_func (st, CELL, 1)) return p * 0;
  146. return p;
  147. }
  148. path
  149. edit_table_rep::search_cell (path fp, int row, int col) {
  150. return search_cell (search_row (fp, row), col);
  151. }
  152. /******************************************************************************
  153. * Analyzing with statements in format
  154. ******************************************************************************/
  155. void
  156. edit_table_rep::with_raw_read (tree with, int& i1, int& j1, int& i2, int& j2) {
  157. i1= as_int (with[0]);
  158. i2= as_int (with[1]);
  159. j1= as_int (with[2]);
  160. j2= as_int (with[3]);
  161. }
  162. void
  163. edit_table_rep::with_decode (int nr_rows, int nr_cols,
  164. int& i1, int& j1, int& i2, int& j2)
  165. {
  166. i1= (i1>=0? i1-1: nr_rows+i1);
  167. i2= (i2> 0? i2-1: nr_rows+i2);
  168. j1= (j1>=0? j1-1: nr_cols+j1);
  169. j2= (j2> 0? j2-1: nr_cols+j2);
  170. }
  171. void
  172. edit_table_rep::with_decode (int nr_rows, int nr_cols,
  173. int& I1, int& J1, int& I2, int& J2,
  174. int& i1, int& j1, int& i2, int& j2)
  175. {
  176. i1= I1; j1= J1; i2= I2; j2=J2;
  177. with_decode (nr_rows, nr_cols, i1, j1, i2, j2);
  178. }
  179. void
  180. edit_table_rep::with_read (tree with, int nr_rows, int nr_cols,
  181. int& i1, int& j1, int& i2, int& j2)
  182. {
  183. with_raw_read (with, i1, j1, i2, j2);
  184. with_decode (nr_rows, nr_cols, i1, j1, i2, j2);
  185. }
  186. void
  187. edit_table_rep::with_read (tree with, int nr_rows, int nr_cols,
  188. int& I1, int& J1, int& I2, int& J2,
  189. int& i1, int& j1, int& i2, int& j2)
  190. {
  191. with_raw_read (with, I1, J1, I2, J2);
  192. i1= I1; j1= J1; i2= I2; j2=J2;
  193. with_decode (nr_rows, nr_cols, i1, j1, i2, j2);
  194. }
  195. /******************************************************************************
  196. * Formatting primitives
  197. ******************************************************************************/
  198. tree
  199. edit_table_rep::table_get_format (path fp) {
  200. tree fm= get_env_value (CELL_FORMAT, fp * 0);
  201. tree st= subtree (et, fp);
  202. return fm * st (0, N(st)-1);
  203. }
  204. void
  205. edit_table_rep::table_set_format (path fp, string var, tree val) {
  206. table_del_format (fp, var);
  207. tree with (TWITH, var, val);
  208. tree st= subtree (et, fp);
  209. insert (fp * (N(st)-1), tree (TFORMAT, with));
  210. }
  211. tree
  212. edit_table_rep::table_get_format (path fp, string var) {
  213. tree st= table_get_format (fp);
  214. int k, n= N(st);
  215. tree val= get_env_value (var);
  216. for (k=0; k<n; k++)
  217. if (is_func (st[k], TWITH, 2) && (st[k][0] == var))
  218. val= st[k][1];
  219. return val;
  220. }
  221. void
  222. edit_table_rep::table_del_format (path fp, string var) {
  223. tree st= subtree (et, fp);
  224. int k, n= N(st);
  225. for (k=n-2; k>=0; k--)
  226. if (is_func (st[k], TWITH, 2))
  227. if ((var == "") || (var == st[k][0]))
  228. remove (fp * k, 1);
  229. }
  230. void
  231. edit_table_rep::table_set_format (
  232. path fp, int I1, int J1, int I2, int J2, string var, tree val)
  233. {
  234. table_del_format (fp, I1, J1, I2, J2, var);
  235. tree with (CWITH);
  236. with << as_string (I1) << as_string (I2)
  237. << as_string (J1) << as_string (J2)
  238. << var << val;
  239. tree st= subtree (et, fp);
  240. insert (fp * (N(st)-1), tree (TFORMAT, with));
  241. }
  242. tree
  243. edit_table_rep::table_get_format (
  244. path fp, int I1, int J1, int I2, int J2, string var)
  245. {
  246. int i1, j1, i2, j2;
  247. int nr_rows, nr_cols;
  248. tree st= table_get_format (fp);
  249. table_get_extents (fp, nr_rows, nr_cols);
  250. with_decode (nr_rows, nr_cols, I1, J1, I2, J2, i1, j1, i2, j2);
  251. int k, n= N(st);
  252. tree val= get_env_value (var);
  253. for (k=0; k<n; k++)
  254. if (is_func (st[k], CWITH, 6) && (st[k][4] == var)) {
  255. int row1, col1, row2, col2;
  256. with_read (st[k], nr_rows, nr_cols, row1, col1, row2, col2);
  257. if ((row1<=i1) && (col1<=j1) && (row2>=i2) && (col2>=j2))
  258. val= st[k][5];
  259. }
  260. return val;
  261. }
  262. void
  263. edit_table_rep::table_del_format (
  264. path fp, int I1, int J1, int I2, int J2, string var)
  265. {
  266. int i1, j1, i2, j2;
  267. int nr_rows, nr_cols;
  268. tree st= subtree (et, fp);
  269. table_get_extents (fp, nr_rows, nr_cols);
  270. with_decode (nr_rows, nr_cols, I1, J1, I2, J2, i1, j1, i2, j2);
  271. int k, n= N(st);
  272. for (k=n-2; k>=0; k--)
  273. if (is_func (st[k], CWITH, 6))
  274. if ((var == "") || (var == st[k][4])) {
  275. int row1, col1, row2, col2;
  276. with_read (st[k], nr_rows, nr_cols, row1, col1, row2, col2);
  277. if ((row1>=i1) && (col1>=j1) && (row2<=i2) && (col2<=j2))
  278. remove (fp * k, 1);
  279. }
  280. }
  281. void
  282. edit_table_rep::table_get_format (
  283. path fp, string var, tree** val, int nr_rows, int nr_cols)
  284. {
  285. int i, j;
  286. tree def_val= get_env_value (var, fp);
  287. for (i=0; i<nr_rows; i++)
  288. for (j=0; j<nr_cols; j++)
  289. val[i][j]= def_val;
  290. tree st= table_get_format (fp);
  291. int k, n= N(st);
  292. for (k=0; k<n; k++)
  293. if (is_func (st[k], CWITH, 6) && (st[k][4] == var)) {
  294. int row1, col1, row2, col2;
  295. with_read (st[k], nr_rows, nr_cols, row1, col1, row2, col2);
  296. for (i=row1; i<=row2; i++)
  297. for (j=col1; j<=col2; j++)
  298. val[i][j]= st[k][5];
  299. }
  300. }
  301. void
  302. edit_table_rep::table_individualize (path fp, string var) {
  303. int nr_rows, nr_cols;
  304. tree st= subtree (et, fp);
  305. table_get_extents (fp, nr_rows, nr_cols);
  306. int k, n= N(st);
  307. for (k=n-2; k>=0; k--)
  308. if (is_func (st[k], CWITH, 6))
  309. if ((var == "") || (var == st[k][4])) {
  310. int i, j, row1, col1, row2, col2;
  311. with_read (st[k], nr_rows, nr_cols, row1, col1, row2, col2);
  312. if ((row1==row2) && (col1==col2)) continue;
  313. row1= max (row1, 0); row2= min (row2, nr_rows-1);
  314. col1= max (col1, 0); col2= min (col2, nr_cols-1);
  315. tree ins_format (TFORMAT);
  316. for (i=row1; i<=row2; i++)
  317. for (j=col1; j<=col2; j++) {
  318. tree with (CWITH);
  319. with << as_string (i+1) << as_string (i+1)
  320. << as_string (j+1) << as_string (j+1)
  321. << copy (st[k][4]) << copy (st[k][5]) << copy (st[k][6]);
  322. ins_format << with;
  323. }
  324. remove (fp * k, 1);
  325. insert (fp * k, ins_format);
  326. }
  327. }
  328. void
  329. edit_table_rep::table_format_center (path fp, int row, int col) {
  330. int nr_rows, nr_cols;
  331. tree st= subtree (et, fp);
  332. table_get_extents (fp, nr_rows, nr_cols);
  333. int Row1= row+1;
  334. int Col1= col+1;
  335. int Row2= row-nr_rows;
  336. int Col2= col-nr_cols;
  337. int k, n= N(st);
  338. for (k=n-2; k>=0; k--)
  339. if (is_func (st[k], CWITH, 6)) {
  340. int I1, I2, J1, J2, i1, i2, j1, j2;
  341. with_read (st[k], nr_rows, nr_cols, I1, J1, I2, J2, i1, j1, i2, j2);
  342. if (i1 == row) I1= Row1;
  343. else if (i1 < row) I1= i1+1;
  344. else I1= i1-nr_rows;
  345. if (i2 == row) I2= Row2;
  346. else if (i2 < row) I2= i2+1;
  347. else I2= i2-nr_rows;
  348. if (j1 == col) J1= Col1;
  349. else if (j1 < col) J1= j1+1;
  350. else J1= j1-nr_cols;
  351. if (j2 == col) J2= Col2;
  352. else if (j2 < col) J2= j2+1;
  353. else J2= j2-nr_cols;
  354. assign (fp * path (k, 0), as_string (I1));
  355. assign (fp * path (k, 1), as_string (I2));
  356. assign (fp * path (k, 2), as_string (J1));
  357. assign (fp * path (k, 3), as_string (J2));
  358. }
  359. }
  360. /******************************************************************************
  361. * Inserting and deleteing new rows and columns
  362. ******************************************************************************/
  363. void
  364. edit_table_rep::table_get_extents (path fp, int& nr_rows, int& nr_cols) {
  365. ::table_get_extents (subtree (et, fp), nr_rows, nr_cols);
  366. }
  367. void
  368. edit_table_rep::table_set_extents (path fp, int nr_rows, int nr_cols) {
  369. int old_rows, old_cols;
  370. table_get_extents (fp, old_rows, old_cols);
  371. if (nr_rows > old_rows || nr_cols > old_cols)
  372. table_insert (fp, old_rows, old_cols,
  373. max (0, nr_rows - old_rows),
  374. max (0, nr_cols - old_cols));
  375. if (nr_rows < old_rows || nr_cols < old_cols)
  376. table_remove (fp, nr_rows, nr_cols,
  377. max (0, old_rows - nr_rows),
  378. max (0, old_cols - nr_cols));
  379. }
  380. void
  381. edit_table_rep::table_get_limits (
  382. path fp, int& i1, int& j1, int& i2, int& j2)
  383. {
  384. i1= max (1, as_int (table_get_format (fp, TABLE_MIN_ROWS)));
  385. j1= max (1, as_int (table_get_format (fp, TABLE_MIN_COLS)));
  386. i2= as_int (table_get_format (fp, TABLE_MAX_ROWS));
  387. j2= as_int (table_get_format (fp, TABLE_MAX_COLS));
  388. if (i2<i1) i2= 0x7fffffff;
  389. if (j2<i1) j2= 0x7fffffff;
  390. }
  391. void
  392. edit_table_rep::table_remove (path fp, int row, int col, int delr, int delc) {
  393. path p= search_table (fp);
  394. int nr_rows, nr_cols;
  395. table_get_extents (p, nr_rows, nr_cols);
  396. tree T= subtree (et, p);
  397. if (delr>0)
  398. if (row+delr <= N(T)) {
  399. if (delr == N(T)) {
  400. destroy_table ();
  401. return;
  402. }
  403. remove (p * row, delr);
  404. }
  405. T= subtree (et, p);
  406. if (delc>0)
  407. for (row=0; row<N(T); row++) {
  408. path q= search_row (p, row);
  409. tree R= subtree (et, q);
  410. if (col+delc <= N(R)) {
  411. if (delc == N(R)) {
  412. destroy_table ();
  413. return;
  414. }
  415. remove (q * col, delc);
  416. }
  417. }
  418. tree st= subtree (et, fp);
  419. if (!is_func (st, TFORMAT)) return;
  420. int k, n= N(st);
  421. for (k=n-2; k>=0; k--)
  422. if (is_func (st[k], CWITH, 6)) {
  423. int I1, I2, J1, J2, i1, i2, j1, j2;
  424. with_read (st[k], nr_rows, nr_cols, I1, J1, I2, J2, i1, j1, i2, j2);
  425. if (delr>0) {
  426. if ((row<=i1) && (i2<row+delr)) { remove (fp * k, 1); continue; }
  427. if ((I1>0) && (i1>=row))
  428. assign (fp * path (k, 0), as_string (I1- min (delr, i1- row)));
  429. if ((I1<0) && (i1<row+delr))
  430. assign (fp * path (k, 0), as_string (I1+ delr+ min (0, row- 1- i1)));
  431. if ((I2>0) && (i2>=row))
  432. assign (fp * path (k, 1), as_string (I2- min (delr, i2- row)));
  433. if ((I2<0) && (i2<row+delr))
  434. assign (fp * path (k, 1), as_string (I2+ delr+ min (0, row- 1- i2)));
  435. }
  436. if (delc>0) {
  437. if ((col<=j1) && (j2<col+delc)) { remove (fp * k, 1); continue; }
  438. if ((J1>0) && (j1>=col))
  439. assign (fp * path (k, 2), as_string (J1- min (delc, j1- col)));
  440. if ((J1<0) && (j1<col+delc))
  441. assign (fp * path (k, 2), as_string (J1+ delc+ min (0, col- 1- j1)));
  442. if ((J2>0) && (j2>=col))
  443. assign (fp * path (k, 3), as_string (J2- min (delc, j2- col)));
  444. if ((J2<0) && (j2<col+delc))
  445. assign (fp * path (k, 3), as_string (J2+ delc+ min (0, col- 1- j2)));
  446. }
  447. }
  448. }
  449. void
  450. edit_table_rep::table_insert (path fp, int row, int col, int insr, int insc) {
  451. path p= search_table (fp);
  452. int nr_rows, nr_cols;
  453. table_get_extents (p, nr_rows, nr_cols);
  454. tree T= subtree (et, p);
  455. if (insr>0)
  456. if (row <= N(T))
  457. insert (p * row, empty_table (insr, nr_cols));
  458. T= subtree (et, p);
  459. if (insc>0)
  460. for (row=0; row<N(T); row++) {
  461. path q= search_row (p, row);
  462. tree R= subtree (et, q);
  463. if (col <= N(R))
  464. insert (q * col, empty_row (insc));
  465. }
  466. tree st= subtree (et, fp);
  467. if (!is_func (st, TFORMAT)) return;
  468. int k, n= N(st);
  469. for (k=n-2; k>=0; k--)
  470. if (is_func (st[k], CWITH, 6)) {
  471. int I1, I2, J1, J2, i1, i2, j1, j2;
  472. with_read (st[k], nr_rows, nr_cols, I1, J1, I2, J2, i1, j1, i2, j2);
  473. if (insr>0) {
  474. bool flag= (I1<=0) || (I2>=0);
  475. if ((I1>0) && ((i1>row) || (flag && (i1==row))))
  476. assign (fp* path (k,0), as_string (I1+insr));
  477. if ((I1<0) && (i1<row))
  478. assign (fp* path (k,0), as_string (I1-insr));
  479. if ((I2>0) && (i2>=row))
  480. assign (fp* path (k,1), as_string (I2+insr));
  481. if ((I2<0) && ((i2<row-1) || (flag && (i2==row-1))))
  482. assign (fp* path (k,1), as_string (I2-insr));
  483. }
  484. if (insc>0) {
  485. bool flag= (J1<=0) || (J2>=0);
  486. if ((J1>0) && ((j1>col) || (flag && (j1==col))))
  487. assign (fp * path (k,2), as_string (J1+insc));
  488. if ((J1<0) && (j1<col))
  489. assign (fp * path (k,2), as_string (J1-insc));
  490. if ((J2>0) && (j2>=col))
  491. assign (fp * path (k,3), as_string (J2+insc));
  492. if ((J2<0) && ((j2<col-1) || (flag && (j2==col-1))))
  493. assign (fp * path (k,3), as_string (J2-insc));
  494. }
  495. }
  496. }
  497. /******************************************************************************
  498. * Cursor positioning
  499. ******************************************************************************/
  500. void
  501. edit_table_rep::table_bound (
  502. path fp, int& row1, int& col1, int& row2, int& col2)
  503. {
  504. fp= search_format (fp);
  505. if (!is_func (subtree (et, fp), TFORMAT)) return;
  506. int i, j, ii, jj, nr_rows, nr_cols;
  507. table_get_extents (fp, nr_rows, nr_cols);
  508. tree** rs= tm_new_array<tree*> (nr_rows);
  509. tree** cs= tm_new_array<tree*> (nr_rows);
  510. for (i=0; i<nr_rows; i++) {
  511. rs[i]= tm_new_array<tree> (nr_cols);
  512. cs[i]= tm_new_array<tree> (nr_cols);
  513. }
  514. table_get_format (fp, CELL_ROW_SPAN, rs, nr_rows, nr_cols);
  515. table_get_format (fp, CELL_COL_SPAN, cs, nr_rows, nr_cols);
  516. for (i=0; i<nr_rows; i++)
  517. for (j=0; j<nr_cols; j++) {
  518. int m= min (as_int (rs[i][j]), nr_rows-i);
  519. int n= min (as_int (rs[i][j]), nr_cols-j);
  520. if ((m>1) || (n>1)) {
  521. if ((row1 < i+m) && (col1 < j+n) && (row2 >= i) && (col2 >= j)) {
  522. row1= min (row1, i);
  523. col1= min (col1, j);
  524. row2= max (row2, i+m-1);
  525. col2= max (col2, j+n-1);
  526. }
  527. for (ii=0; ii<m; ii++)
  528. for (jj=0; jj<n; jj++) {
  529. rs[i+ii][j+jj]= "0";
  530. cs[i+ii][j+jj]= "0";
  531. }
  532. }
  533. }
  534. for (i=0; i<nr_rows; i++) {
  535. tm_delete_array (rs[i]);
  536. tm_delete_array (cs[i]);
  537. }
  538. tm_delete_array (rs);
  539. tm_delete_array (cs);
  540. }
  541. void
  542. edit_table_rep::table_go_to (path fp, int row, int col, bool at_start) {
  543. int nr_rows, nr_cols;
  544. fp= search_format (fp);
  545. table_get_extents (fp, nr_rows, nr_cols);
  546. if (row<0) row= 0;
  547. if (col<0) col= 0;
  548. if (row>=nr_rows) row= nr_rows-1;
  549. if (col>=nr_cols) col= nr_cols-1;
  550. if (is_func (subtree (et, fp), TFORMAT)) {
  551. int row2= row, col2= col;
  552. table_bound (fp, row, col, row2, col2);
  553. }
  554. path q= search_cell (fp, row, col);
  555. go_to_border (q, at_start);
  556. }
  557. void
  558. edit_table_rep::table_go_to_border (path fp, bool right) {
  559. while ((rp < fp) && (is_func (subtree (et, path_up (fp)), TFORMAT)))
  560. fp= path_up (fp);
  561. if ((rp < fp) &&
  562. is_document (subtree (et, path_up (fp))) &&
  563. (rp < path_up (fp)) &&
  564. is_extension (subtree (et, path_up (fp, 2)), 1))
  565. fp= path_up (fp);
  566. if ((rp < fp) && is_extension (subtree (et, path_up (fp)), 1))
  567. fp= path_up (fp);
  568. if ((rp < fp) && is_func (subtree (et, path_up (fp)), SUBTABLE, 1))
  569. fp= path_up (fp);
  570. go_to_border (fp, right);
  571. }
  572. void
  573. edit_table_rep::back_table (path p, bool forward) {
  574. while (true) {
  575. tree st= subtree (et, p);
  576. if (!is_func (st, TFORMAT)) break;
  577. if (!is_func (st [N(st)-1], TABLE)) {
  578. back_general (p, forward);
  579. return;
  580. }
  581. p= p * (N(st)-1);
  582. }
  583. while (rp < p) {
  584. tree st= subtree (et, p);
  585. if (is_func (st, TABLE)) break;
  586. p= path_up (p);
  587. }
  588. if (!(rp < p)) return;
  589. if (forward) table_go_to (p, 0, 0, true);
  590. else {
  591. int nr_rows, nr_cols;
  592. table_get_extents (p, nr_rows, nr_cols);
  593. table_go_to (p, nr_rows-1, nr_cols-1, false);
  594. }
  595. }
  596. void
  597. edit_table_rep::back_in_table (tree t, path p, bool forward) {
  598. if (is_func (t, TFORMAT) &&
  599. (is_func (subtree (et, path_up (p, 2)), INACTIVE) || in_source ()))
  600. {
  601. remove_empty_argument (p, forward);
  602. return;
  603. }
  604. int i, j, row, col, nr_rows, nr_cols;
  605. p= search_table (row, col);
  606. if (is_nil (p)) return;
  607. table_get_extents (p, nr_rows, nr_cols);
  608. bool flag=true;
  609. for (j=0; j<nr_cols; j++) {
  610. path q= search_cell (p, row, j);
  611. flag= flag && is_empty_cell (subtree (et, q));
  612. }
  613. if (flag) {
  614. int i1, j1, i2, j2;
  615. path fp= search_format ();
  616. if (is_nil (fp)) return;
  617. table_get_limits (fp, i1, j1, i2, j2);
  618. if (nr_rows-1 >= i1) {
  619. table_remove_row (forward, true);
  620. return;
  621. }
  622. }
  623. flag= true;
  624. for (i=0; i<nr_rows; i++) {
  625. path q= search_cell (p, i, col);
  626. flag= flag && is_empty_cell (subtree (et, q));
  627. }
  628. if (flag) {
  629. int i1, j1, i2, j2;
  630. path fp= search_format ();
  631. if (is_nil (fp)) return;
  632. table_get_limits (fp, i1, j1, i2, j2);
  633. if (nr_cols-1 >= j1) {
  634. table_remove_column (forward, true);
  635. return;
  636. }
  637. }
  638. flag=true;
  639. for (i=0; i<nr_rows; i++)
  640. for (j=0; j<nr_cols; j++) {
  641. path q= search_cell (p, i, j);
  642. flag= flag && is_empty_cell (subtree (et, q));
  643. }
  644. if (flag) {
  645. destroy_table ();
  646. return;
  647. }
  648. if (forward) {
  649. if (col<(nr_cols-1)) { table_go_to (p, row, col+1, true); return; }
  650. if (row<(nr_rows-1)) { table_go_to (p, row+1, 0, true); return; }
  651. }
  652. else {
  653. if (col>0) { table_go_to (p, row, col-1, false); return; }
  654. if (row>0) { table_go_to (p, row-1, nr_cols-1, false); return; }
  655. }
  656. table_go_to_border (p, !forward);
  657. }
  658. /******************************************************************************
  659. * Routines for subtables
  660. ******************************************************************************/
  661. tree
  662. edit_table_rep::table_get_subtable (
  663. path fp, int row1, int col1, int row2, int col2)
  664. {
  665. return table_get_subtable (fp, row1, col1, row2, col2, false);
  666. }
  667. tree
  668. edit_table_rep::table_get_subtable (
  669. path fp, int row1, int col1, int row2, int col2, bool recurse)
  670. {
  671. path p= search_table (fp);
  672. int i, j, nr_rows, nr_cols;
  673. table_get_extents (p, nr_rows, nr_cols);
  674. tree st= subtree (et, p);
  675. tree subtable (TABLE, row2+1-row1);
  676. for (i=row1; i<=row2; i++) {
  677. tree sr= st[i];
  678. tree sub_row (ROW, col2+1-col1);
  679. while (is_func (sr, TFORMAT)) sr= sr[N(sr)-1];
  680. for (j=col1; j<=col2; j++)
  681. sub_row[j-col1]= copy (sr[j]);
  682. subtable[i-row1]= sub_row;
  683. }
  684. st= subtree (et, fp);
  685. if ((!recurse) && (!is_func (st, TFORMAT))) return subtable;
  686. if (recurse) st= table_get_format (fp);
  687. else st= st (0, N(st)-1);
  688. int k, n= N(st);
  689. tree sub_format (TFORMAT);
  690. for (k=0; k<n; k++)
  691. if (is_func (st[k], CWITH, 6)) {
  692. int I1, I2, J1, J2, i1, i2, j1, j2;
  693. with_read (st[k], nr_rows, nr_cols, I1, J1, I2, J2, i1, j1, i2, j2);
  694. if ((i1<=row2) && (i2>=row1) && (j1<=col2) && (j2>=col1)) {
  695. I1= min (max (0, i1- row1), row2- row1) + 1;
  696. I2= min (max (0, i2- row1), row2- row1) + 1;
  697. J1= min (max (0, j1- col1), col2- col1) + 1;
  698. J2= min (max (0, j2- col1), col2- col1) + 1;
  699. tree with (CWITH);
  700. with << as_string (I1) << as_string (I2)
  701. << as_string (J1) << as_string (J2)
  702. << copy (st[k][4]) << copy (st[k][5]);
  703. sub_format << with;
  704. }
  705. }
  706. sub_format << subtable;
  707. return sub_format;
  708. }
  709. static tree
  710. shift_subtable (tree st, int sh_row, int sh_col) {
  711. st= copy (st);
  712. int k, n= N(st);
  713. for (k=0; k<n-1; k++)
  714. if (is_func (st[k], CWITH, 6)) {
  715. st[k][0]= as_string (as_int (st[k][0]) + sh_row);
  716. st[k][1]= as_string (as_int (st[k][1]) + sh_row);
  717. st[k][2]= as_string (as_int (st[k][2]) + sh_col);
  718. st[k][3]= as_string (as_int (st[k][3]) + sh_col);
  719. }
  720. return st;
  721. }
  722. void
  723. edit_table_rep::table_write_subtable (
  724. path fp, int row, int col, tree subt)
  725. {
  726. int nr_rows, nr_cols, sub_rows, sub_cols;
  727. table_get_extents (fp, nr_rows, nr_cols);
  728. ::table_get_extents (subt, sub_rows, sub_cols);
  729. if ((nr_rows < row+sub_rows) || (nr_cols < col+sub_cols)) return;
  730. if (is_func (subtree (et, fp), TFORMAT) &&
  731. is_func (subt, TFORMAT))
  732. {
  733. tree sh_subt= shift_subtable (subt, row, col);
  734. sh_subt= sh_subt (0, N(sh_subt)-1);
  735. tree st= subtree (et, fp);
  736. insert (fp * (N(st)-1), sh_subt);
  737. subt= subt [N(subt)-1];
  738. }
  739. int i, j;
  740. for (i=0; i<sub_rows; i++) {
  741. path rp = search_row (fp, i+row);
  742. tree subr= subt[i];
  743. while (is_func (subr, TFORMAT)) subr= subr [N(subr)-1];
  744. for (j=0; j<sub_cols; j++) {
  745. path cp = search_cell (rp, j+col);
  746. tree subc= subr[j];
  747. while (is_func (subc, TFORMAT)) subc= subc [N(subr)-1];
  748. if (is_func (subc, CELL, 1)) subc= subc[0];
  749. assign (cp, copy (subc));
  750. }
  751. }
  752. }
  753. void
  754. edit_table_rep::table_hor_insert_subtable (path fp, int col, tree subt) {
  755. int nr_rows, nr_cols, sub_rows, sub_cols;
  756. table_get_extents (fp, nr_rows, nr_cols);
  757. ::table_get_extents (subt, sub_rows, sub_cols);
  758. if (sub_rows != nr_rows) return;
  759. table_insert (fp, 0, col, 0, sub_cols);
  760. table_write_subtable (fp, 0, col, subt);
  761. }
  762. void
  763. edit_table_rep::table_ver_insert_subtable (path fp, int row, tree subt) {
  764. int nr_rows, nr_cols, sub_rows, sub_cols;
  765. table_get_extents (fp, nr_rows, nr_cols);
  766. ::table_get_extents (subt, sub_rows, sub_cols);
  767. if (sub_cols != nr_cols) return;
  768. table_insert (fp, row, 0, sub_rows, 0);
  769. table_write_subtable (fp, row, 0, subt);
  770. }
  771. /******************************************************************************
  772. * Decorations
  773. ******************************************************************************/
  774. void
  775. edit_table_rep::table_force_decoration (path fp, int row, int col) {
  776. row++; col++;
  777. tree old= table_get_format (fp, row, col, row, col, CELL_DECORATION);
  778. if (old == "") {
  779. tree f (TFORMAT, tree (TABLE, tree (ROW, tree (TMARKER))));
  780. table_set_format (fp, row, col, row, col, CELL_DECORATION, f);
  781. }
  782. }
  783. static void
  784. search_decoration (tree T, int& row, int& col) {
  785. while (is_func (T, TFORMAT)) T= T [N(T)-1];
  786. for (row=0; row<N(T); row++) {
  787. tree R= T[row];
  788. while (is_func (R, TFORMAT)) R= R [N(R)-1];
  789. for (col=0; col<N(R); col++) {
  790. tree C= R[col];
  791. while (is_func (C, TFORMAT)) C= C [N(C)-1];
  792. if (C == tree (TMARKER)) return;
  793. }
  794. }
  795. FAILED ("decoration not found");
  796. }
  797. static tree
  798. table_format_undecorate (tree st, int row, int col, int dec_row, int dec_col) {
  799. tree fm (TFORMAT);
  800. int k, n= N(st);
  801. for (k=0; k<n-1; k++)
  802. if ((as_int (st[k][0]) <= (row+1)) && (as_int (st[k][1]) >= (row+1)) &&
  803. (as_int (st[k][2]) <= (col+1)) && (as_int (st[k][3]) >= (col+1)))
  804. if (is_func (st[k], CWITH, 6) && (st[k][4] != CELL_DECORATION)) {
  805. tree with= copy (st[k]);
  806. with[0]= as_string (dec_row+1);
  807. with[1]= as_string (dec_row+1);
  808. with[2]= as_string (dec_col+1);
  809. with[3]= as_string (dec_col+1);
  810. fm << with;
  811. }
  812. return fm;
  813. }
  814. static tree
  815. table_undecorate (tree st, int row, int col) {
  816. int k, n= N(st);
  817. for (k=0; k<n-1; k++)
  818. if ((as_int (st[k][0]) == (row+1)) && (as_int (st[k][2]) == (col+1)))
  819. if (is_func (st[k], CWITH, 6) && (st[k][4] == CELL_DECORATION)) {
  820. int dec_row= 0, dec_col= 0;
  821. tree T= copy (st[k][5]);
  822. search_decoration (T, dec_row, dec_col);
  823. table_set (T, dec_row, dec_col, table_get (st[n-1], row, col));
  824. tree F= table_format_undecorate (st, row, col, dec_row, dec_col);
  825. return F * T;
  826. }
  827. FAILED ("decoration not found");
  828. return "";
  829. }
  830. void
  831. edit_table_rep::table_hor_decorate (path fp, int col, int cbef, int caft) {
  832. tree st= subtree (et, fp);
  833. if (!is_func (st, TFORMAT)) return;
  834. if (cbef+caft == 0) return;
  835. int i, j, k, nr_rows, nr_cols;
  836. path p= search_table (fp);
  837. table_get_extents (p, nr_rows, nr_cols);
  838. table_individualize (fp, CELL_DECORATION);
  839. for (i=0; i<nr_rows; i++)
  840. for (j=col-cbef; j<=col+caft; j++)
  841. table_force_decoration (fp, i, j);
  842. tree t1, t2;
  843. if (caft>0)
  844. t2= table_get_subtable (fp, 0, col+1 , nr_rows-1, col+caft, true);
  845. if (cbef>0)
  846. t1= table_get_subtable (fp, 0, col-cbef, nr_rows-1, col-1 , true);
  847. if (caft>0) table_remove (fp, 0, col+1 , 0, caft);
  848. if (cbef>0) table_remove (fp, 0, col-cbef, 0, cbef);
  849. col -= cbef;
  850. st= subtree (et, fp);
  851. int n= N(st);
  852. for (k=0; k<n-1; k++)
  853. if (is_func (st[k], CWITH, 6) && (st[k][4] == CELL_DECORATION)) {
  854. int i1, j1, i2, j2;
  855. with_read (st[k], nr_rows, nr_cols, i1, j1, i2, j2);
  856. if (j1 != col) continue;
  857. for (j=0; j<caft; j++) {
  858. tree inst= table_undecorate (t2, i1, j);
  859. int sub_rows, sub_cols;
  860. ::table_get_extents (st[k][5], sub_rows, sub_cols);
  861. table_hor_insert_subtable (fp * path (k, 5), sub_cols, inst);
  862. }
  863. for (j=cbef-1; j>=0; j--) {
  864. tree inst= table_undecorate (t1, i1, j);
  865. table_hor_insert_subtable (fp * path (k, 5), 0, inst);
  866. }
  867. }
  868. }
  869. void
  870. edit_table_rep::table_ver_decorate (path fp, int row, int rbef, int raft) {
  871. tree st= subtree (et, fp);
  872. if (!is_func (st, TFORMAT)) return;
  873. if (rbef+raft == 0) return;
  874. int i, j, k, nr_rows, nr_cols;
  875. path p= search_table (fp);
  876. table_get_extents (p, nr_rows, nr_cols);
  877. table_individualize (fp, CELL_DECORATION);
  878. for (i=row-rbef; i<=row+raft; i++)
  879. for (j=0; j<nr_cols; j++)
  880. table_force_decoration (fp, i, j);
  881. tree t1, t2;
  882. if (raft>0)
  883. t2= table_get_subtable (fp, row+1 , 0, row+raft, nr_cols-1, true);
  884. if (rbef>0)
  885. t1= table_get_subtable (fp, row-rbef, 0, row-1 , nr_cols-1, true);
  886. if (raft>0) table_remove (fp, row+1 , 0, raft, 0);
  887. if (rbef>0) table_remove (fp, row-rbef, 0, rbef, 0);
  888. row -= rbef;
  889. st= subtree (et, fp);
  890. int n= N(st);
  891. for (k=0; k<n-1; k++)
  892. if (is_func (st[k], CWITH, 6) && (st[k][4] == CELL_DECORATION)) {
  893. int i1, j1, i2, j2;
  894. with_read (st[k], nr_rows, nr_cols, i1, j1, i2, j2);
  895. if (i1 != row) continue;
  896. for (i=0; i<raft; i++) {
  897. tree inst= table_undecorate (t2, i, j1);
  898. int sub_rows, sub_cols;
  899. ::table_get_extents (st[k][5], sub_rows, sub_cols);
  900. table_ver_insert_subtable (fp * path (k, 5), sub_rows, inst);
  901. }
  902. for (i=rbef-1; i>=0; i--) {
  903. tree inst= table_undecorate (t1, i, j1);
  904. table_ver_insert_subtable (fp * path (k, 5), 0, inst);
  905. }
  906. }
  907. }
  908. /******************************************************************************
  909. * User interface
  910. ******************************************************************************/
  911. void
  912. edit_table_rep::make_table (int nr_rows, int nr_cols) {
  913. //cout << "make_table " << nr_rows << ", " << nr_cols << "\n";
  914. tree T= empty_table (nr_rows, nr_cols);
  915. path p (0, 0, 0, 0);
  916. tree format_T (TFORMAT, T);
  917. insert_tree (format_T, path (N(format_T)-1, p));
  918. int i1, j1, i2, j2;
  919. path fp= search_format ();
  920. if (is_nil (fp)) return;
  921. table_get_limits (fp, i1, j1, i2, j2);
  922. if ((nr_rows<i1) || (nr_cols<j1)) {
  923. T= empty_table (max (nr_rows, i1), max (nr_cols, j1));
  924. format_T= tree (TFORMAT, T);
  925. assign (fp, format_T);
  926. go_to (fp * path (N(format_T)-1, p));
  927. }
  928. string hyphen= as_string (table_get_format (fp, TABLE_HYPHEN));
  929. if (hyphen == "y") {
  930. path q= fp;
  931. if (is_extension (subtree (et, path_up (q)), 1)) q= path_up (q);
  932. tree st= subtree (et, path_up (q));
  933. if (is_document (st)) insert_node (fp * 0, DOCUMENT);
  934. else if (is_concat (st) && is_document (subtree (et, path_up (q, 2)))) {
  935. int n= N(st), l= last_item (q);
  936. insert_node (fp * 0, DOCUMENT);
  937. if (l != (n-1)) {
  938. split (path_inc (q));
  939. correct_concat (path_inc (path_up (q)));
  940. }
  941. if (l != 0) {
  942. split (q);
  943. correct_concat (path_inc (path_up (q)));
  944. }
  945. correct_concat (path_up (q));
  946. }
  947. }
  948. table_correct_block_content ();
  949. set_message (concat (kbd_shortcut ("(structured-insert-down)"),
  950. ": new row",
  951. kbd_shortcut ("(structured-insert-right)"),
  952. ": new column"),
  953. "table");
  954. }
  955. void
  956. edit_table_rep::make_subtable (int nr_rows, int nr_cols) {
  957. path cp= search_upwards (CELL);
  958. if (is_nil (cp)) return;
  959. tree T= empty_table (nr_rows, nr_cols);
  960. path p (0, 0, 0, 0);
  961. T= tree (TFORMAT, T);
  962. p= path (N(T)-1, p);
  963. T= tree (SUBTABLE, T);
  964. p= path (0, p);
  965. assign (cp * 0, T);
  966. go_to (cp * path (0, p));
  967. table_correct_block_content ();
  968. set_message (concat (kbd_shortcut ("(structured-insert-down)"),
  969. ": new row",
  970. kbd_shortcut ("(structured-insert-right)"),
  971. ": new column"),
  972. "table");
  973. }
  974. void
  975. edit_table_rep::destroy_table () {
  976. path fp= search_format ();
  977. if (is_nil (fp)) return;
  978. while (rp < fp) {
  979. tree st= subtree (et, path_up (fp));
  980. if (!is_func (st, TFORMAT)) break;
  981. fp= path_up (fp);
  982. }
  983. if ((rp < fp) &&
  984. is_document (subtree (et, path_up (fp))) &&
  985. (rp < path_up (fp)) &&
  986. is_extension (subtree (et, path_up (fp, 2)), 1))
  987. fp= path_up (fp);
  988. if ((rp < fp) && is_extension (subtree (et, path_up (fp)), 1))
  989. fp= path_up (fp);
  990. if ((rp < fp) && is_func (subtree (et, path_up (fp)), SUBTABLE, 1))
  991. fp= path_up (fp);
  992. assign (fp, "");
  993. correct (path_up (fp));
  994. }
  995. void
  996. edit_table_rep::table_disactivate () {
  997. path fp= search_format ();
  998. if (is_nil (fp)) return;
  999. tree st= subtree (et, fp);
  1000. if (!is_func (st, TFORMAT)) return;
  1001. insert_node (fp * 0, INACTIVE);
  1002. set_message ("return: reactivate", "deactivate table");
  1003. }
  1004. void
  1005. edit_table_rep::table_extract_format () {
  1006. path fp= search_format ();
  1007. if (is_nil (fp)) return;
  1008. tree fm= table_get_format (fp);
  1009. fm << "";
  1010. if (is_extension (subtree (et, path_up (fp)), 1)) fp= path_up (fp);
  1011. assign (fp, fm);
  1012. go_to (fp * path (N(fm)-1, 0));
  1013. }
  1014. void
  1015. edit_table_rep::table_insert_row (bool forward) {
  1016. int row, col;
  1017. path fp= search_format (row, col);
  1018. if (is_nil (fp)) return;
  1019. int nr_rows, nr_cols, i1, j1, i2, j2;
  1020. table_get_extents (fp, nr_rows, nr_cols);
  1021. table_get_limits (fp, i1, j1, i2, j2);
  1022. if (nr_rows+1 > i2) return;
  1023. table_insert (fp, row + (forward? 1: 0), col, 1, 0);
  1024. table_go_to (fp, row + (forward? 1: 0), col);
  1025. table_correct_block_content ();
  1026. }
  1027. void
  1028. edit_table_rep::table_insert_column (bool forward) {
  1029. int row, col;
  1030. path fp= search_format (row, col);
  1031. if (is_nil (fp)) return;
  1032. int nr_rows, nr_cols, i1, j1, i2, j2;
  1033. table_get_extents (fp, nr_rows, nr_cols);
  1034. table_get_limits (fp, i1, j1, i2, j2);
  1035. if (nr_cols+1 > j2) return;
  1036. table_insert (fp, row, col + (forward? 1: 0), 0, 1);
  1037. table_go_to (fp, row, col + (forward? 1: 0));
  1038. table_correct_block_content ();
  1039. }
  1040. void
  1041. edit_table_rep::table_remove_row (bool forward, bool flag) {
  1042. int row, col;
  1043. path fp= search_format (row, col);
  1044. if (is_nil (fp)) return;
  1045. int nr_rows, nr_cols, i1, j1, i2, j2;
  1046. table_get_extents (fp, nr_rows, nr_cols);
  1047. table_get_limits (fp, i1, j1, i2, j2);
  1048. if (nr_rows-1 < i1) destroy_table ();
  1049. else if (flag) {
  1050. table_remove (fp, row, col, 1, 0);
  1051. int ncol= col;
  1052. if ((!forward) && (col == 0)) ncol= nr_cols-1;
  1053. if (forward && (col == nr_cols-1)) ncol= 0;
  1054. table_go_to (fp, max (0, row + (forward? 0: -1)), ncol, forward);
  1055. }
  1056. else {
  1057. if (!forward) row--;
  1058. if (row >= 0) table_remove (fp, row, col, 1, 0);
  1059. if (row < nr_rows-1 && forward) table_go_to (fp, row, col, forward);
  1060. else if (forward || row < 0) table_go_to_border (fp, !forward);
  1061. }
  1062. table_correct_block_content ();
  1063. }
  1064. void
  1065. edit_table_rep::table_remove_column (bool forward, bool flag) {
  1066. int row, col;
  1067. path fp= search_format (row, col);
  1068. if (is_nil (fp)) return;
  1069. int nr_rows, nr_cols, i1, j1, i2, j2;
  1070. table_get_extents (fp, nr_rows, nr_cols);
  1071. table_get_limits (fp, i1, j1, i2, j2);
  1072. if (nr_cols-1 < j1) destroy_table ();
  1073. else if (flag) {
  1074. table_remove (fp, row, col, 0, 1);
  1075. int ncol= max (0, col + (forward? 0: -1));
  1076. if ((!forward) && (col == 0)) ncol= nr_cols-1;
  1077. if (forward && (col == nr_cols-1)) ncol= 0;
  1078. table_go_to (fp, row, ncol, forward);
  1079. }
  1080. else {
  1081. if (!forward) col--;
  1082. if (col >= 0) table_remove (fp, row, col, 0, 1);
  1083. if (col < nr_cols-1 && forward) table_go_to (fp, row, col, forward);
  1084. else if (forward || col < 0) table_go_to_border (fp, !forward);
  1085. }
  1086. table_correct_block_content ();
  1087. }
  1088. int
  1089. edit_table_rep::table_nr_rows () {
  1090. int nr_rows, nr_cols;
  1091. path fp= search_format ();
  1092. if (is_nil (fp)) return -1;
  1093. table_get_extents (fp, nr_rows, nr_cols);
  1094. return nr_rows;
  1095. }
  1096. int
  1097. edit_table_rep::table_nr_columns () {
  1098. int nr_rows, nr_cols;
  1099. path fp= search_format ();
  1100. if (is_nil (fp)) return -1;
  1101. table_get_extents (fp, nr_rows, nr_cols);
  1102. return nr_cols;
  1103. }
  1104. void
  1105. edit_table_rep::table_set_extents (int rows, int cols) {
  1106. path fp= search_format ();
  1107. if (is_nil (fp)) return;
  1108. int min_rows, min_cols, max_rows, max_cols;
  1109. table_get_limits (fp, min_rows, min_cols, max_rows, max_cols);
  1110. rows= min (max_rows, max (min_rows, rows));
  1111. cols= min (max_cols, max (min_cols, cols));
  1112. table_set_extents (fp, rows, cols);
  1113. }
  1114. int
  1115. edit_table_rep::table_which_row () {
  1116. int row, col;
  1117. path fp= search_format (row, col);
  1118. if (is_nil (fp)) return 0;
  1119. return row+1;
  1120. }
  1121. int
  1122. edit_table_rep::table_which_column () {
  1123. int row, col;
  1124. path fp= search_format (row, col);
  1125. if (is_nil (fp)) return 0;
  1126. return col+1;
  1127. }
  1128. path
  1129. edit_table_rep::table_search_cell (int row, int col) {
  1130. int nr_rows, nr_cols;
  1131. path fp= search_format ();
  1132. if (is_nil (fp)) return path ();
  1133. table_get_extents (fp, nr_rows, nr_cols);
  1134. if (row>0) row--; else row+=nr_rows;
  1135. if (col>0) col--; else col+=nr_cols;
  1136. if ((row<0) || (row>=nr_rows) || (col<0) || (col>=nr_cols)) return path ();
  1137. return search_cell (fp, row, col);
  1138. }
  1139. void
  1140. edit_table_rep::table_go_to (int row, int col) {
  1141. int nr_rows, nr_cols;
  1142. path fp= search_format ();
  1143. if (is_nil (fp)) return;
  1144. table_get_extents (fp, nr_rows, nr_cols);
  1145. if (row>0) row--; else row+=nr_rows;
  1146. if (col>0) col--; else col+=nr_cols;
  1147. if ((row<0) || (row>=nr_rows) || (col<0) || (col>=nr_cols)) return;
  1148. table_go_to (fp, row, col);
  1149. }
  1150. void
  1151. edit_table_rep::table_set_format (string var, tree val) {
  1152. if (val == "") table_del_format (var);
  1153. else if (selection_active_table (false)) {
  1154. int row1, col1, row2, col2;
  1155. path fp= selection_get_subtable (row1, col1, row2, col2);
  1156. if (is_nil (fp)) return;
  1157. table_set_format (fp, var, val);
  1158. }
  1159. else {
  1160. path fp= search_format ();
  1161. if (is_nil (fp)) return;
  1162. table_set_format (fp, var, val);
  1163. }
  1164. }
  1165. string
  1166. edit_table_rep::table_get_format (string var) {
  1167. path fp= search_format ();
  1168. if (is_nil (fp)) return "";
  1169. return as_string (table_get_format (fp, var));
  1170. }
  1171. void
  1172. edit_table_rep::table_del_format (string var) {
  1173. if (selection_active_table (false)) {
  1174. int row1, col1, row2, col2;
  1175. path fp= selection_get_subtable (row1, col1, row2, col2);
  1176. if (is_nil (fp)) return;
  1177. table_del_format (fp, var);
  1178. }
  1179. else {
  1180. path fp= search_format ();
  1181. if (is_nil (fp)) return;
  1182. table_del_format (fp, var);
  1183. }
  1184. }
  1185. void
  1186. edit_table_rep::table_format_center () {
  1187. int row, col;
  1188. path fp= search_format (row, col);
  1189. if (is_nil (fp)) return;
  1190. table_format_center (fp, row, col);
  1191. }
  1192. void
  1193. edit_table_rep::table_row_decoration (bool forward) {
  1194. int row, col, nr_rows, nr_cols;
  1195. path fp= search_format (row, col);
  1196. if (is_nil (fp)) return;
  1197. table_get_extents (fp, nr_rows, nr_cols);
  1198. if ((!forward) && (row > 0)) table_ver_decorate (fp, row, 1, 0);
  1199. if (forward && (row < (nr_rows-1))) table_ver_decorate (fp, row, 0, 1);
  1200. }
  1201. void
  1202. edit_table_rep::table_column_decoration (bool forward) {
  1203. int row, col, nr_rows, nr_cols;
  1204. path fp= search_format (row, col);
  1205. if (is_nil (fp)) return;
  1206. table_get_extents (fp, nr_rows, nr_cols);
  1207. if ((!forward) && (col > 0)) table_hor_decorate (fp, col, 1, 0);
  1208. if (forward && (col < (nr_cols-1))) table_hor_decorate (fp, col, 0, 1);
  1209. }
  1210. void
  1211. edit_table_rep::table_correct_block_content () {
  1212. int nr_rows, nr_cols;
  1213. path fp= search_format ();
  1214. if (is_nil (fp)) return;
  1215. table_get_extents (fp, nr_rows, nr_cols);
  1216. int row, col;
  1217. for (row= 0; row < nr_rows; row++)
  1218. for (col= 0; col < nr_cols; col++) {
  1219. path cp= search_cell (fp, row, col);
  1220. tree st= subtree (et, cp);
  1221. tree t1= table_get_format (fp, row+1, col+1, row+1, col+1, CELL_BLOCK);
  1222. tree t2= table_get_format (fp, row+1, col+1, row+1, col+1, CELL_HYPHEN);
  1223. bool f1= (t1 == "no" || (t1 == "auto" && t2 == "n"));
  1224. bool f2= (t1 == "yes" || (t1 == "auto" && is_atomic (t2) && t2 != "n"));
  1225. if (f1 && is_document (st) && N(st) == 1)
  1226. remove_node (cp * 0);
  1227. else if (f2 && !is_document (st))
  1228. insert_node (cp * 0, DOCUMENT);
  1229. }
  1230. }
  1231. void
  1232. edit_table_rep::set_cell_mode (string mode) {
  1233. cell_mode= mode;
  1234. }
  1235. string
  1236. edit_table_rep::get_cell_mode () {
  1237. return cell_mode;
  1238. }
  1239. void
  1240. edit_table_rep::cell_set_format (string var, tree val) {
  1241. if (selection_active_table (false)) {
  1242. int row1, col1, row2, col2, rows, cols;
  1243. path fp= selection_get_subtable (row1, col1, row2, col2);
  1244. row1++; col1++; row2++; col2++;
  1245. table_get_extents (fp, rows, cols);
  1246. if (rows > row1 && row1 <= 2 && row2 == rows) row2= -1;
  1247. if (cols > col1 && col1 <= 2 && col2 == cols) col2= -1;
  1248. table_set_format (fp, row1, col1, row2, col2, var, val);
  1249. }
  1250. else {
  1251. int row, col;
  1252. path fp= search_format (row, col); row++; col++;
  1253. if (is_nil (fp)) return;
  1254. if (cell_mode=="row")
  1255. table_set_format (fp, row, 1, row, -1, var, val);
  1256. else if (cell_mode=="column")
  1257. table_set_format (fp, 1, col, -1, col, var, val);
  1258. else if (cell_mode=="table")
  1259. table_set_format (fp, 1, 1, -1, -1, var, val);
  1260. else table_set_format (fp, row, col, row, col, var, val);
  1261. }
  1262. table_correct_block_content ();
  1263. }
  1264. string
  1265. edit_table_rep::cell_get_format (string var) {
  1266. int row, col;
  1267. path fp= search_format (row, col); row++; col++;
  1268. if (is_nil (fp)) return "";
  1269. if (cell_mode=="row")
  1270. return as_string (table_get_format (fp, row, 1, row, -1, var));
  1271. else if (cell_mode=="column")
  1272. return as_string (table_get_format (fp, 1, col, -1, col, var));
  1273. else if (cell_mode=="table")
  1274. return as_string (table_get_format (fp, 1, 1, -1, -1, var));
  1275. else return as_string (table_get_format (fp, row, col, row, col, var));
  1276. }
  1277. void
  1278. edit_table_rep::cell_del_format (string var) {
  1279. if (selection_active_table (false)) {
  1280. int row1, col1, row2, col2;
  1281. path fp= selection_get_subtable (row1, col1, row2, col2);
  1282. table_del_format (fp, row1+1, col1+1, row2+1, col2+1, var);
  1283. }
  1284. else {
  1285. int row, col;
  1286. path fp= search_format (row, col); row++; col++;
  1287. if (is_nil (fp)) return;
  1288. if (cell_mode=="row") table_del_format (fp, row, 1, row, -1, var);
  1289. else if (cell_mode=="column") table_del_format (fp, 1, col, -1, col, var);
  1290. else if (cell_mode=="table") table_del_format (fp, 1, 1, -1, -1, var);
  1291. else table_del_format (fp, row, col, row, col, var);
  1292. }
  1293. table_correct_block_content ();
  1294. }
  1295. void
  1296. edit_table_rep::table_test () {
  1297. path fp= search_format ();
  1298. if (is_nil (fp)) return;
  1299. cout << table_get_format (fp) << "\n";
  1300. }