home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume17 / xbae / part08 < prev    next >
Encoding:
Text File  |  1992-03-22  |  50.6 KB  |  1,956 lines

  1. Newsgroups: comp.sources.x
  2. Path: uunet!zaphod.mps.ohio-state.edu!mips!msi!dcmartin
  3. From: Andrew Wason <aw@bae.bellcore.com>
  4. Subject: v17i035: Xbae widgets (MOTIF), Part08/12
  5. Message-ID: <1992Mar23.180140.16221@msi.com>
  6. Originator: dcmartin@fascet
  7. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  8. Organization: Molecular Simulations, Inc.
  9. References: <csx-17i028-xbae@uunet.UU.NET>
  10. Date: Mon, 23 Mar 1992 18:01:40 GMT
  11. Approved: dcmartin@msi.com
  12.  
  13. Submitted-by: Andrew Wason <aw@bae.bellcore.com>
  14. Posting-number: Volume 17, Issue 35
  15. Archive-name: xbae/part08
  16.  
  17. Submitted-by: aw@jello
  18. Archive-name: Xbae/part08
  19.  
  20. ---- Cut Here and feed the following to sh ----
  21. #!/bin/sh
  22. # this is Xbae.shar.08 (part 8 of Xbae)
  23. # do not concatenate these parts, unpack them in order with /bin/sh
  24. # file Xbae/src/Matrix.c continued
  25. #
  26. if test ! -r _shar_seq_.tmp; then
  27.     echo 'Please unpack part 1 first!'
  28.     exit 1
  29. fi
  30. (read Scheck
  31.  if test "$Scheck" != 8; then
  32.     echo Please unpack part "$Scheck" next!
  33.     exit 1
  34.  else
  35.     exit 0
  36.  fi
  37. ) < _shar_seq_.tmp || exit 1
  38. if test ! -f _shar_wnt_.tmp; then
  39.     echo 'x - still skipping Xbae/src/Matrix.c'
  40. else
  41. echo 'x - continuing file Xbae/src/Matrix.c'
  42. sed 's/^X//' << 'SHAR_EOF' >> 'Xbae/src/Matrix.c' &&
  43. X
  44. X    /*
  45. X     * Malloc a new row array for each row. Initialize it with foreground.
  46. X     * Use the new column size.
  47. X     */
  48. X    for (i = current->matrix.rows; i < new->matrix.rows; i++) {
  49. X        new->matrix.colors[i] =
  50. X        (Pixel *) XtMalloc(new->matrix.columns * sizeof(Pixel));
  51. X        for (j = 0; j < new->matrix.columns; j++)
  52. X        new->matrix.colors[i][j] = new->manager.foreground;
  53. X    }
  54. X
  55. X    safe_rows = current->matrix.rows;
  56. X    }
  57. X
  58. X    /*
  59. X     * Deleting rows
  60. X     */
  61. X    if (new->matrix.rows < current->matrix.rows) {
  62. X    for (i = new->matrix.rows; i < current->matrix.rows; i++)
  63. X        XtFree((XtPointer) new->matrix.colors[i]);
  64. X    safe_rows = new->matrix.rows;
  65. X    }
  66. X
  67. X    /*
  68. X     * Adding columns
  69. X     */
  70. X    if (new->matrix.columns > current->matrix.columns) {
  71. X    /*
  72. X     * Realloc each row array. Do not touch any rows added/deleted above
  73. X     * (use safe_rows)
  74. X     */
  75. X    for (i = 0; i < safe_rows; i++) {
  76. X        int j;
  77. X
  78. X        new->matrix.colors[i] =
  79. X        (Pixel *) XtRealloc((char *)new->matrix.colors[i],
  80. X                    new->matrix.columns * sizeof(Pixel));
  81. X        for (j = current->matrix.columns; j < new->matrix.columns; j++)
  82. X        new->matrix.colors[i][j] = new->manager.foreground;
  83. X    }
  84. X    }
  85. X
  86. X    /*
  87. X     * Deleting columns
  88. X     *   if (new->matrix.columns < current->matrix.columns)
  89. X     * We don't bother to realloc, just leave some wasted space.
  90. X     * XXX is this a problem?
  91. X     */
  92. }
  93. X
  94. /*
  95. X * Add rows to the internal cells data structure.
  96. X * If rows or labels is NULL, add empty rows.
  97. X */
  98. static void
  99. AddRowsToTable(mw, position, rows, labels, colors, num_rows)
  100. XXbaeMatrixWidget mw;
  101. int position;
  102. String *rows;
  103. String *labels;
  104. Pixel *colors;
  105. int num_rows;
  106. {
  107. X    int i, j;
  108. X
  109. X    /*
  110. X     * Realloc a larger array of row pointers and a larger label array
  111. X     */
  112. X    mw->matrix.cells = (String **) XtRealloc((char *)mw->matrix.cells,
  113. X                         (mw->matrix.rows + num_rows) *
  114. X                         sizeof(String *));
  115. X    if (mw->matrix.row_labels)
  116. X    mw->matrix.row_labels =
  117. X        (String *) XtRealloc((char *)mw->matrix.row_labels,
  118. X                 (mw->matrix.rows + num_rows) *
  119. X                 sizeof(String));
  120. X    if (mw->matrix.colors)
  121. X    mw->matrix.colors = (Pixel **) XtRealloc((char *)mw->matrix.colors,
  122. X                         (mw->matrix.rows + num_rows) *
  123. X                         sizeof(Pixel *));
  124. X
  125. X    mw->matrix.selected_cells =
  126. X    (Boolean **) XtRealloc((char *)mw->matrix.selected_cells,
  127. X                   (mw->matrix.rows + num_rows) *
  128. X                   sizeof(Boolean *));
  129. X
  130. X    /*
  131. X     * If we are inserting rows into the middle, we need to make room.
  132. X     * XXX we are assuming bcopy can handle overlapping moves.
  133. X     */
  134. X    if (position < mw->matrix.rows) {
  135. X    bcopy(&mw->matrix.cells[position],
  136. X          &mw->matrix.cells[position + num_rows],
  137. X          (mw->matrix.rows - position) * sizeof(String *));
  138. X    if (mw->matrix.row_labels)
  139. X        bcopy(&mw->matrix.row_labels[position],
  140. X          &mw->matrix.row_labels[position + num_rows],
  141. X          (mw->matrix.rows - position) * sizeof(String));
  142. X    if (mw->matrix.colors)
  143. X        bcopy(&mw->matrix.colors[position],
  144. X          &mw->matrix.colors[position + num_rows],
  145. X          (mw->matrix.rows - position) * sizeof(Pixel *));
  146. X    bcopy(&mw->matrix.selected_cells[position],
  147. X          &mw->matrix.selected_cells[position + num_rows],
  148. X          (mw->matrix.rows - position) * sizeof(Boolean *));
  149. X    }
  150. X
  151. X    /*
  152. X     * Malloc a new row array for each new row. Copy the label for each row.
  153. X     * If no label was passed in, use a NULL String. Malloc a new Pixel
  154. X     * and Boolean row array for each new row.
  155. X     */
  156. X    for (i = 0; i < num_rows; i++) {
  157. X    mw->matrix.cells[i + position] =
  158. X        (String *) XtMalloc(mw->matrix.columns * sizeof(String));
  159. X    if (mw->matrix.row_labels)
  160. X        mw->matrix.row_labels[i + position] =
  161. X        labels ? XtNewString(labels[i]) : XtNewString("");
  162. X    if (mw->matrix.colors)
  163. X        mw->matrix.colors[i + position] =
  164. X        (Pixel *) XtMalloc(mw->matrix.columns * sizeof(Pixel));
  165. X    mw->matrix.selected_cells[i + position] =
  166. X        (Boolean *) XtMalloc(mw->matrix.columns * sizeof(Boolean));
  167. X    }
  168. X
  169. X    /*
  170. X     * Copy the rows arrays passed in into each new row, or if NULL
  171. X     * was passed in initialize each row to NULL Strings. Copy the colors
  172. X     * arrays passed in into each new row, if NULL was passed use foreground.
  173. X     */
  174. X    for (i = 0; i < num_rows; i++)
  175. X    for (j = 0; j < mw->matrix.columns; j++) {
  176. X        mw->matrix.cells[i + position][j] =
  177. X        rows
  178. X            ? XtNewString(rows[i * mw->matrix.columns + j])
  179. X            : XtNewString("");
  180. X        if (mw->matrix.colors)
  181. X        mw->matrix.colors[i + position][j] =
  182. X            colors
  183. X            ? colors[i]
  184. X            : mw->manager.foreground;
  185. X        mw->matrix.selected_cells[i + position][j] = False;
  186. X    }
  187. X
  188. X    mw->matrix.rows += num_rows;
  189. }
  190. X
  191. /*
  192. X * Delete rows from the internal cells data structure.
  193. X */
  194. static void
  195. DeleteRowsFromTable(mw, position, num_rows)
  196. XXbaeMatrixWidget mw;
  197. int position;
  198. int num_rows;
  199. {
  200. X    int i, j;
  201. X
  202. X    /*
  203. X     * We don't bother to realloc, we will just have some wasted space.
  204. X     * XXX is this a problem?
  205. X     */
  206. X
  207. X    /*
  208. X     * Free all the cells in the rows being deleted and the rows themselves.
  209. X     * Also free the String row labels.  Free the color arrays for the rows
  210. X     * being deleted.
  211. X     */
  212. X    for (i = position; i < position + num_rows; i++) {
  213. X    for (j = 0; j < mw->matrix.columns; j++)
  214. X        XtFree((XtPointer) mw->matrix.cells[i][j]);
  215. X    XtFree((XtPointer) mw->matrix.cells[i]);
  216. X    if (mw->matrix.row_labels)
  217. X        XtFree((XtPointer) mw->matrix.row_labels[i]);
  218. X    if (mw->matrix.colors)
  219. X        XtFree((XtPointer) mw->matrix.colors[i]);
  220. X    XtFree((XtPointer) mw->matrix.selected_cells[i]);
  221. X    }
  222. X
  223. X    /*
  224. X     * Copy those rows which are below the ones deleted, up.
  225. X     * (unless we deleted rows from the bottom).
  226. X     * XXX we assume bcopy can handle overlapping moves
  227. X     */
  228. X    if (position + num_rows < mw->matrix.rows) {
  229. X    bcopy(&mw->matrix.cells[position + num_rows],
  230. X          &mw->matrix.cells[position],
  231. X          (mw->matrix.rows - position - num_rows) * sizeof(String *));
  232. X    if (mw->matrix.row_labels)
  233. X        bcopy(&mw->matrix.row_labels[position + num_rows],
  234. X          &mw->matrix.row_labels[position],
  235. X          (mw->matrix.rows - position - num_rows) * sizeof(String));
  236. X    if (mw->matrix.colors)
  237. X        bcopy(&mw->matrix.colors[position + num_rows],
  238. X          &mw->matrix.colors[position],
  239. X          (mw->matrix.rows - position - num_rows) * sizeof(Pixel *));
  240. X    bcopy(&mw->matrix.selected_cells[position + num_rows],
  241. X          &mw->matrix.selected_cells[position],
  242. X          (mw->matrix.rows - position - num_rows) * sizeof(Boolean *));
  243. X    }
  244. X
  245. X    mw->matrix.rows -= num_rows;
  246. }
  247. X
  248. /*
  249. X * Add columns to the internal cells data structure.
  250. X * If columns or labels is NULL, add empty columns.
  251. X * If max_lengths is NULL, widths will be used.
  252. X * If alignments is NULL, use XmALIGNMENT_BEGINNING.
  253. X * If label_alignments is NULL, use alignments, or if it is NULL
  254. X *   XmALIGNMENT_BEGINNING.
  255. X * widths must not be NULL.
  256. X */
  257. static void
  258. AddColumnsToTable(mw, position, columns, labels, widths, max_lengths,
  259. X          alignments, label_alignments, colors, num_columns)
  260. XXbaeMatrixWidget mw;
  261. int position;
  262. String *columns;
  263. String *labels;
  264. short *widths;
  265. int *max_lengths;
  266. unsigned char *alignments;
  267. unsigned char *label_alignments;
  268. Pixel *colors;
  269. int num_columns;
  270. {
  271. X    int i, j;
  272. X
  273. X    /*
  274. X     * Realloc larger cells, widths, max_lengths, alignments,
  275. X     * colors, selected_cells, labels and label lines arrays.
  276. X     */
  277. X
  278. X    for (i = 0; i < mw->matrix.rows; i++) {
  279. X    mw->matrix.cells[i] = 
  280. X        (String *) XtRealloc((char *) mw->matrix.cells[i],
  281. X                 (mw->matrix.columns + num_columns) *
  282. X                 sizeof(String));
  283. X    if (mw->matrix.colors)
  284. X        mw->matrix.colors[i] =
  285. X        (Pixel *) XtRealloc((char *)mw->matrix.colors[i],
  286. X                     (mw->matrix.columns + num_columns) *
  287. X                     sizeof(Pixel));
  288. X    mw->matrix.selected_cells[i] =
  289. X        (Boolean *) XtRealloc((char *)mw->matrix.selected_cells[i],
  290. X                   (mw->matrix.columns + num_columns) *
  291. X                   sizeof(Boolean));
  292. X    }
  293. X
  294. X    mw->matrix.column_widths =
  295. X    (short *) XtRealloc((char *) mw->matrix.column_widths,
  296. X                (mw->matrix.columns + num_columns) *
  297. X                sizeof(short));
  298. X
  299. X    if (mw->matrix.column_max_lengths)
  300. X    mw->matrix.column_max_lengths =
  301. X        (int *) XtRealloc((char *) mw->matrix.column_max_lengths,
  302. X                  (mw->matrix.columns + num_columns) *
  303. X                  sizeof(int));
  304. X
  305. X    if (mw->matrix.column_alignments)
  306. X    mw->matrix.column_alignments =
  307. X        (unsigned char *)
  308. X        XtRealloc((char *)mw->matrix.column_alignments,
  309. X              (mw->matrix.columns + num_columns) *
  310. X              sizeof(unsigned char));
  311. X
  312. X    if (mw->matrix.column_label_alignments)
  313. X    mw->matrix.column_label_alignments =
  314. X        (unsigned char *) XtRealloc((char *)mw->matrix.
  315. X                    column_label_alignments,
  316. X                    (mw->matrix.columns + num_columns) *
  317. X                    sizeof(unsigned char));
  318. X
  319. X    if (mw->matrix.column_labels) {
  320. X    mw->matrix.column_labels =
  321. X        (String *) XtRealloc((char *)mw->matrix.column_labels,
  322. X                 (mw->matrix.columns + num_columns) *
  323. X                 sizeof(String));
  324. X    mw->matrix.column_label_lines =
  325. X        (ColumnLabelLines) XtRealloc((char *)mw->matrix.column_label_lines,
  326. X                     (mw->matrix.columns + num_columns) *
  327. X                     sizeof(ColumnLabelLinesRec));
  328. X    }
  329. X
  330. X    /*
  331. X     * If we are inserting columns into the middle, we need to make room.
  332. X     * XXX we are assuming bcopy can handle overlapping moves.
  333. X     */
  334. X    if (position < mw->matrix.columns) {
  335. X    bcopy(&mw->matrix.column_widths[position],
  336. X          &mw->matrix.column_widths[position + num_columns],
  337. X          (mw->matrix.columns - position) * sizeof(short));
  338. X
  339. X    if (mw->matrix.column_max_lengths)
  340. X        bcopy(&mw->matrix.column_max_lengths[position],
  341. X          &mw->matrix.column_max_lengths[position + num_columns],
  342. X          (mw->matrix.columns - position) * sizeof(int));
  343. X
  344. X    if (mw->matrix.column_alignments)
  345. X        bcopy(&mw->matrix.column_alignments[position],
  346. X          &mw->matrix.column_alignments[position + num_columns],
  347. X          (mw->matrix.columns - position) * sizeof(unsigned char));
  348. X
  349. X    if (mw->matrix.column_label_alignments)
  350. X        bcopy(&mw->matrix.column_label_alignments[position],
  351. X          &mw->matrix.column_label_alignments[position + num_columns],
  352. X          (mw->matrix.columns - position) * sizeof(unsigned char));
  353. X
  354. X    if (mw->matrix.column_labels) {
  355. X        bcopy(&mw->matrix.column_labels[position],
  356. X          &mw->matrix.column_labels[position + num_columns],
  357. X          (mw->matrix.columns - position) * sizeof(String));
  358. X        bcopy(&mw->matrix.column_label_lines[position],
  359. X          &mw->matrix.column_label_lines[position + num_columns],
  360. X          (mw->matrix.columns - position) *
  361. X          sizeof(ColumnLabelLinesRec));
  362. X    }
  363. X
  364. X    /*
  365. X     * Shift the columns in each row.
  366. X     */
  367. X    for (i = 0; i < mw->matrix.rows; i++) {
  368. X        bcopy(&mw->matrix.cells[i][position],
  369. X          &mw->matrix.cells[i][position + num_columns],
  370. X          (mw->matrix.columns - position) * sizeof(String));
  371. X        if (mw->matrix.colors)
  372. X        bcopy(&mw->matrix.colors[i][position],
  373. X              &mw->matrix.colors[i][position + num_columns],
  374. X              (mw->matrix.columns - position) * sizeof(Pixel));
  375. X        bcopy(&mw->matrix.selected_cells[i][position],
  376. X          &mw->matrix.selected_cells[i][position + num_columns],
  377. X          (mw->matrix.columns - position) * sizeof(Boolean));
  378. X    }
  379. X    }
  380. X
  381. X    /*
  382. X     * Copy all of the passed in info into each new column
  383. X     * (except column_positions which will be recalculated below).
  384. X     * If columns or labels is NULL, add empty columns.
  385. X     * If max_lengths is NULL, widths will be used.
  386. X     * If alignments is NULL, use XmALIGNMENT_BEGINNING.
  387. X     * If label_alignments is NULL, use XmALIGNMENT_BEGINNING
  388. X     * If labels is NULL, use NULL strings.
  389. X     * If colors is NULL, use foreground.
  390. X     */
  391. X    for (j = 0; j < num_columns; j++) {
  392. X    mw->matrix.column_widths[j + position] = widths[j];
  393. X
  394. X    if (mw->matrix.column_max_lengths)
  395. X        mw->matrix.column_max_lengths[j + position] =
  396. X        max_lengths ? max_lengths[j] : (int)widths[j];
  397. X
  398. X    if (mw->matrix.column_alignments)
  399. X        mw->matrix.column_alignments[j + position] =
  400. X        alignments ? alignments[j] : XmALIGNMENT_BEGINNING;
  401. X
  402. X    if (mw->matrix.column_label_alignments)
  403. X        mw->matrix.column_label_alignments[j + position] =
  404. X        label_alignments ? label_alignments[j] : XmALIGNMENT_BEGINNING;
  405. X
  406. X    if (mw->matrix.column_labels) {
  407. X        mw->matrix.column_labels[j + position] =
  408. X        labels ? XtNewString(labels[j]) : XtNewString("");
  409. X        ParseColumnLabel(mw->matrix.column_labels[j + position],
  410. X                 &mw->matrix.column_label_lines[j + position]);
  411. X    }
  412. X
  413. X    /*
  414. X     * Add this new column to each row.
  415. X     */
  416. X    for (i = 0; i < mw->matrix.rows; i++) {
  417. X        mw->matrix.cells[i][j + position] =
  418. X        columns
  419. X            ? XtNewString(columns[i * num_columns + j])
  420. X            : XtNewString("");
  421. X        if (mw->matrix.colors)
  422. X        mw->matrix.colors[i][j + position] =
  423. X            colors
  424. X            ? colors[j]
  425. X            : mw->manager.foreground;
  426. X        mw->matrix.selected_cells[i][j + position] = False;
  427. X    }
  428. X    }
  429. X
  430. X    mw->matrix.columns += num_columns;
  431. X    GetCellTotalWidth(mw);
  432. X
  433. X    /*
  434. X     * See if the max number of column label lines changed
  435. X     */
  436. X    if (mw->matrix.column_labels) {
  437. X    int end;
  438. X    end = position + num_columns;
  439. X    for (i = position; i < end; i++)
  440. X        if (mw->matrix.column_label_lines[i].lines >
  441. X        mw->matrix.column_label_maxlines)
  442. X        mw->matrix.column_label_maxlines =
  443. X            mw->matrix.column_label_lines[i].lines;
  444. X    }
  445. X
  446. X    /*
  447. X     * Recalculate the column positions
  448. X     */
  449. X    FreeColumnPositions(mw);
  450. X    mw->matrix.column_positions = CreateColumnPositions(mw);
  451. X    GetColumnPositions(mw);
  452. }
  453. X
  454. /*
  455. X * Delete columns from the internal cells data structure.
  456. X */
  457. static void
  458. DeleteColumnsFromTable(mw, position, num_columns)
  459. XXbaeMatrixWidget mw;
  460. int position;
  461. int num_columns;
  462. {
  463. X    int i, j;
  464. X
  465. X    /*
  466. X     * Free all the cells in the columns being deleted.
  467. X     * Also free the String column labels and the associated ColumnLabelLines
  468. X     * lengths arrays.
  469. X     */
  470. X    for (j = position; j < position + num_columns; j++) {
  471. X    for (i = 0; i < mw->matrix.rows; i++)
  472. X        XtFree((XtPointer) mw->matrix.cells[i][j]);
  473. X    if (mw->matrix.column_labels) {
  474. X        XtFree((XtPointer) mw->matrix.column_labels[j]);
  475. X        XtFree((XtPointer) mw->matrix.column_label_lines[j].lengths);
  476. X    }
  477. X    }
  478. X
  479. X    /*
  480. X     * Shift those columns after the ones being deleted, left.
  481. X     * (unless we deleted columns from the right).
  482. X     * XXX we assume bcopy can handle overlapping moves
  483. X     */
  484. X    if (position + num_columns < mw->matrix.columns) {
  485. X    bcopy(&mw->matrix.column_widths[position + num_columns],
  486. X          &mw->matrix.column_widths[position],
  487. X          (mw->matrix.columns - position - num_columns) * sizeof(short));
  488. X
  489. X    if (mw->matrix.column_max_lengths)
  490. X        bcopy(&mw->matrix.column_max_lengths[position + num_columns],
  491. X          &mw->matrix.column_max_lengths[position],
  492. X          (mw->matrix.columns - position - num_columns) * sizeof(int));
  493. X
  494. X    if (mw->matrix.column_alignments)
  495. X        bcopy(&mw->matrix.column_alignments[position + num_columns],
  496. X          &mw->matrix.column_alignments[position],
  497. X          (mw->matrix.columns - position - num_columns) *
  498. X          sizeof(unsigned char));
  499. X
  500. X    if (mw->matrix.column_label_alignments)
  501. X        bcopy(&mw->matrix.column_label_alignments[position + num_columns],
  502. X          &mw->matrix.column_label_alignments[position],
  503. X          (mw->matrix.columns - position - num_columns) *
  504. X          sizeof(unsigned char));
  505. X
  506. X    if (mw->matrix.column_labels) {
  507. X        bcopy(&mw->matrix.column_labels[position + num_columns],
  508. X          &mw->matrix.column_labels[position],
  509. X          (mw->matrix.columns - position - num_columns) *
  510. X          sizeof(String));
  511. X        bcopy(&mw->matrix.column_label_lines[position + num_columns],
  512. X          &mw->matrix.column_label_lines[position],
  513. X          (mw->matrix.columns - position - num_columns) *
  514. X          sizeof(ColumnLabelLinesRec));
  515. X    }
  516. X
  517. X    /*
  518. X     * Shift the columns in each row.
  519. X     */
  520. X    for (i = 0; i < mw->matrix.rows; i++) {
  521. X        bcopy(&mw->matrix.cells[i][position + num_columns],
  522. X          &mw->matrix.cells[i][position],
  523. X          (mw->matrix.columns - position - num_columns) *
  524. X          sizeof(String));
  525. X        if (mw->matrix.colors)
  526. X        bcopy(&mw->matrix.colors[i][position + num_columns],
  527. X              &mw->matrix.colors[i][position],
  528. X              (mw->matrix.columns - position - num_columns) *
  529. X              sizeof(Pixel));
  530. X        bcopy(&mw->matrix.selected_cells[i][position + num_columns],
  531. X          &mw->matrix.selected_cells[i][position],
  532. X          (mw->matrix.columns - position - num_columns) *
  533. X          sizeof(Boolean));
  534. X    }
  535. X    }
  536. X
  537. X    mw->matrix.columns -= num_columns;
  538. X    GetCellTotalWidth(mw);
  539. X
  540. X    /*
  541. X     * See if the max number of column label lines changed
  542. X     */
  543. X    if (mw->matrix.column_labels) {
  544. X    mw->matrix.column_label_maxlines =
  545. X        mw->matrix.column_label_lines[0].lines;
  546. X    for (i = 1; i < mw->matrix.columns; i++)
  547. X        if (mw->matrix.column_label_lines[i].lines >
  548. X        mw->matrix.column_label_maxlines)
  549. X        mw->matrix.column_label_maxlines =
  550. X            mw->matrix.column_label_lines[i].lines;
  551. X    }
  552. X
  553. X    /*
  554. X     * Recalculate the column positions
  555. X     */
  556. X    FreeColumnPositions(mw);
  557. X    mw->matrix.column_positions = CreateColumnPositions(mw);
  558. X    GetColumnPositions(mw);
  559. }
  560. X
  561. /*
  562. X * Try to make the row specified by the topRow resource (VERT_ORIGIN)
  563. X * be the top row. The row is relative to fixed_rows - so 0 would
  564. X * be the first non-fixed row.
  565. X * If we can't make topRow the top row, make it as close as possible.
  566. X */
  567. static void
  568. AdjustTopRow(mw)
  569. XXbaeMatrixWidget mw;
  570. {
  571. X    int rows_visible = VISIBLE_HEIGHT(mw) / ROW_HEIGHT(mw);
  572. X
  573. X    /*
  574. X     * If we have less than one full row visible, then count it as a full row
  575. X     */
  576. X    if (rows_visible == 0)
  577. X    rows_visible = 1;
  578. X    /*
  579. X     * rows_visible might be inaccurate since Clip may not have been resized
  580. X     */
  581. X    else if (rows_visible > mw->matrix.rows)
  582. X    rows_visible = mw->matrix.rows;
  583. X
  584. X    if (VERT_ORIGIN(mw) > (mw->matrix.rows - (rows_visible +
  585. X                          mw->matrix.fixed_rows)))
  586. X    VERT_ORIGIN(mw) = mw->matrix.rows - (rows_visible +
  587. X                         mw->matrix.fixed_rows);
  588. X    else if (VERT_ORIGIN(mw) < 0)
  589. X    VERT_ORIGIN(mw) = 0;
  590. }
  591. X
  592. /*
  593. X * Return the top and bottom-most visible non-fixed row
  594. X */
  595. static void
  596. GetVisibleRows(mw, top_row, bottom_row)
  597. XXbaeMatrixWidget mw;
  598. int *top_row, *bottom_row;
  599. {
  600. X    *top_row = VERT_ORIGIN(mw) + mw->matrix.fixed_rows;
  601. X    *bottom_row = *top_row + VISIBLE_HEIGHT(mw) / ROW_HEIGHT(mw);
  602. }
  603. X
  604. /*
  605. X * Return the left and right-most visible non-fixed column
  606. X */
  607. static void
  608. GetVisibleColumns(mw, left_column, right_column)
  609. XXbaeMatrixWidget mw;
  610. int *left_column, *right_column;
  611. {
  612. X    *left_column = XtoCol(mw, FIXED_COLUMN_WIDTH(mw) +  HORIZ_ORIGIN(mw));
  613. X    *right_column = XtoCol(mw, FIXED_COLUMN_WIDTH(mw) +  HORIZ_ORIGIN(mw) +
  614. X               VISIBLE_WIDTH(mw));
  615. }
  616. X
  617. /*
  618. X * Return the top and bottom row and left and right column of
  619. X * the visible non-fixed cells
  620. X */
  621. static void
  622. GetVisibleCells(mw, top_row, bottom_row, left_column, right_column)
  623. XXbaeMatrixWidget mw;
  624. int *top_row, *bottom_row, *left_column, *right_column;
  625. {
  626. X    GetVisibleRows(mw, top_row, bottom_row);
  627. X    GetVisibleColumns(mw, left_column, right_column);
  628. }
  629. X
  630. /*
  631. X * Utility function to clear a cell so we can draw something new in it.
  632. X * Does not generate expose events on the cell.
  633. X * Does not check if the cell is actually visible before clearing it.
  634. X */
  635. static void
  636. ClearCell(mw, row, column)
  637. XXbaeMatrixWidget mw;
  638. int row, column;
  639. {
  640. X    int x, y;
  641. X    Window win = CELL_WINDOW(mw, row, column);
  642. X
  643. X    if (!win)
  644. X    return;
  645. X
  646. X    RowColToXY(mw, row, column, &x, &y);
  647. X
  648. X    XClearArea(XtDisplay(mw), win,
  649. X           x, y,
  650. X           COLUMN_WIDTH(mw, column),
  651. X           ROW_HEIGHT(mw),
  652. X           False);
  653. }
  654. X
  655. /*
  656. X * Return True if a row is visible on the screen (not scrolled totally off)
  657. X */
  658. static Boolean
  659. IsRowVisible(mw, row)
  660. XXbaeMatrixWidget mw;
  661. int row;
  662. {
  663. X    /*
  664. X     * If we are not in a fixed row, see if we are on the screen vertically
  665. X     * (fixed rows are always on the screen)
  666. X     */
  667. X    if (row >= mw->matrix.fixed_rows) {
  668. X    row -= mw->matrix.fixed_rows;
  669. X    if (row >= VERT_ORIGIN(mw) &&
  670. X        row <
  671. X        ClipChild(mw)->core.height / ROW_HEIGHT(mw) + VERT_ORIGIN(mw))
  672. X        return True;
  673. X    }
  674. X    else
  675. X    return True;
  676. X
  677. X    return False;
  678. }
  679. X
  680. /*
  681. X * Return True if a column is visible on the screen (not scrolled totally off)
  682. X */
  683. static Boolean
  684. IsColumnVisible(mw, column)
  685. XXbaeMatrixWidget mw;
  686. int column;
  687. {
  688. X    /*
  689. X     * If we are not in a fixed column, see if we are on the screen
  690. X     * horizontally (fixed columns are always on the screen)
  691. X     */
  692. X    if (column >= mw->matrix.fixed_columns) {
  693. X    int x;
  694. X
  695. X    /*
  696. X     * Calculate the x endpoints of this column
  697. X     */
  698. X    x = mw->matrix.column_positions[column] -
  699. X        mw->matrix.column_positions[mw->matrix.fixed_columns];
  700. X
  701. X    /*
  702. X     * Check if we are visible horizontally
  703. X     */
  704. X    if (x + COLUMN_WIDTH(mw, column) > HORIZ_ORIGIN(mw) &&
  705. X        x < ClipChild(mw)->core.width + HORIZ_ORIGIN(mw))
  706. X        return True;
  707. X    }
  708. X    else
  709. X    return True;
  710. X
  711. X    return False;
  712. }
  713. X
  714. /*
  715. X * Return True if a cell is visible on the screen (not scrolled totally off)
  716. X */
  717. static Boolean
  718. IsCellVisible(mw, row, column)
  719. XXbaeMatrixWidget mw;
  720. int row, column;
  721. {
  722. X    return IsRowVisible(mw, row) && IsColumnVisible(mw, column);
  723. }
  724. X
  725. /*
  726. X * Scroll a row so it is visible on the screen.
  727. X */
  728. static void
  729. MakeRowVisible(mw, row)
  730. XXbaeMatrixWidget mw;
  731. int row;
  732. {
  733. X    int rows_visible;
  734. X    int value, slider_size, increment, page_increment, vert_value;
  735. X
  736. X    /*
  737. X     * If we are in a fixed row, we are already visible.
  738. X     */
  739. X    if (row < mw->matrix.fixed_rows)
  740. X    return;
  741. X
  742. X    /*
  743. X     * Take into account fixed_rows.
  744. X     * Calculate the number of rows visible. If less than one full
  745. X     * row is visible, use one full row.
  746. X     */
  747. X    row -= mw->matrix.fixed_rows;
  748. X    rows_visible = VISIBLE_HEIGHT(mw) / ROW_HEIGHT(mw);
  749. X    if (rows_visible == 0)
  750. X    rows_visible = 1;
  751. X    
  752. X    /*
  753. X     * Figure out the new value of the VSB to scroll this cell
  754. X     * onto the screen (the VSB uses row coordinates instead of pixels)
  755. X     */
  756. X    if (row < VERT_ORIGIN(mw))
  757. X    vert_value = row;
  758. X    else if (row >= rows_visible + VERT_ORIGIN(mw))
  759. X    vert_value = row - rows_visible + 1;
  760. X    else
  761. X    vert_value = VERT_ORIGIN(mw);
  762. X    
  763. X    /*
  764. X     * Give the VSB the new value and pass a flag to make it call
  765. X     * our scroll callbacks
  766. X     */
  767. X    if (vert_value != VERT_ORIGIN(mw)) {
  768. X    XmScrollBarGetValues(VertScrollChild(mw), &value,
  769. X                 &slider_size, &increment, &page_increment);
  770. X    XmScrollBarSetValues(VertScrollChild(mw), vert_value,
  771. X                 slider_size, increment, page_increment, True);
  772. X    }
  773. }
  774. X
  775. /*
  776. X * Scroll a column so it is visible on the screen.
  777. X */
  778. static void
  779. MakeColumnVisible(mw, column)
  780. XXbaeMatrixWidget mw;
  781. int column;
  782. {
  783. X    int value, slider_size, increment, page_increment, x, horiz_value;
  784. X
  785. X    /*
  786. X     * If we are in a fixed column, we are already visible.
  787. X     */
  788. X    if (column < mw->matrix.fixed_columns)
  789. X    return;
  790. X
  791. X    /*
  792. X     * Calculate the x position of this column
  793. X     */
  794. X    x = mw->matrix.column_positions[column] -
  795. X    mw->matrix.column_positions[mw->matrix.fixed_columns];
  796. X    
  797. X    /*
  798. X     * Figure out the new value of the HSB to scroll this cell
  799. X     * onto the screen. If the whole cell won't fit, scroll so its
  800. X     * left edge is visible.
  801. X     */
  802. X    if (x < HORIZ_ORIGIN(mw))
  803. X    horiz_value = x;
  804. X    else if (x + COLUMN_WIDTH(mw, column) >
  805. X         VISIBLE_WIDTH(mw) + HORIZ_ORIGIN(mw)) {
  806. X    int off = (x + COLUMN_WIDTH(mw, column)) - (VISIBLE_WIDTH(mw) +
  807. X                            HORIZ_ORIGIN(mw));
  808. X    if (x - off < HORIZ_ORIGIN(mw))
  809. X        horiz_value = x;
  810. X    else
  811. X        horiz_value = HORIZ_ORIGIN(mw) + off;
  812. X    }
  813. X    else
  814. X    horiz_value = HORIZ_ORIGIN(mw);
  815. X    
  816. X    /*
  817. X     * Give the HSB the new value and pass a flag to make it
  818. X     * call our scroll callbacks
  819. X     */
  820. X    if (horiz_value != HORIZ_ORIGIN(mw)) {
  821. X    XmScrollBarGetValues(HorizScrollChild(mw), &value,
  822. X                 &slider_size, &increment, &page_increment);
  823. X    XmScrollBarSetValues(HorizScrollChild(mw), horiz_value,
  824. X                 slider_size, increment, page_increment, True);
  825. X    }
  826. }
  827. X
  828. /*
  829. X * Scrolls a fixed or non-fixed cell so it is visible on the screen.
  830. X */
  831. static void
  832. MakeCellVisible(mw, row, column)
  833. XXbaeMatrixWidget mw;
  834. int row, column;
  835. {
  836. X    MakeRowVisible(mw, row);
  837. X    MakeColumnVisible(mw, column);
  838. }
  839. X
  840. static Boolean
  841. DoCommitEdit(mw)
  842. XXbaeMatrixWidget mw;
  843. {
  844. X    String cell;
  845. X
  846. X    if (!XtIsManaged(TextChild(mw)))
  847. X    return True;
  848. X
  849. X    /*
  850. X     * Get the value the user entered in the textField (this is a copy)
  851. X     */
  852. X    cell = XmTextFieldGetString(TextChild(mw));
  853. X
  854. X    /*
  855. X     * Call the leaveCellCallback to see if we can leave the current cell.
  856. X     */
  857. X    if (mw->matrix.leave_cell_callback) {
  858. X    XbaeMatrixLeaveCellCallbackStruct call_data;
  859. X
  860. X    call_data.reason = XbaeLeaveCellReason;
  861. X    call_data.row = mw->matrix.current_row;
  862. X    call_data.column = mw->matrix.current_column;
  863. X    call_data.value = cell;
  864. X    call_data.doit = True;
  865. X
  866. X    XtCallCallbackList((Widget)mw, mw->matrix.leave_cell_callback,
  867. X               (XtPointer) &call_data);
  868. X
  869. X    /*
  870. X     * Application doesn't want to leave this cell. Make the cell visible
  871. X     * and traverse to it so the user can see where they screwed up.
  872. X     */
  873. X    if (!call_data.doit) {
  874. X        MakeCellVisible(mw,
  875. X                mw->matrix.current_row, mw->matrix.current_column);
  876. X        XmProcessTraversal(TextChild(mw), XmTRAVERSE_CURRENT);
  877. X        XtFree((XtPointer)cell);
  878. X        return False;
  879. X    }
  880. X
  881. X    /*
  882. X     * Use the applications value if it is different.
  883. X     * If the application modified the string inplace, we will pick that
  884. X     * up automatically.
  885. X     */
  886. X    if (call_data.value != cell) {
  887. X        XtFree((XtPointer)cell);
  888. X        cell = call_data.value;
  889. X    }
  890. X    }
  891. X
  892. X    /*
  893. X     * Call the set_cell method to store the new value in the cell and redraw.
  894. X     */
  895. X    (*((XbaeMatrixWidgetClass) XtClass(mw))->matrix_class.set_cell)
  896. X    (mw, mw->matrix.current_row, mw->matrix.current_column, cell);
  897. X
  898. X    XtFree((XtPointer)cell);
  899. X
  900. X    return True;
  901. }
  902. X
  903. /*
  904. X * Matrix set_cell method
  905. X */
  906. static void
  907. SetCell(mw, row, column, value)
  908. XXbaeMatrixWidget mw;
  909. int row, column;
  910. String value;
  911. {
  912. X    if (row >= mw->matrix.rows || row < 0 ||
  913. X    column >= mw->matrix.columns || column < 0) {
  914. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  915. X            "setCell", "badIndex", "XbaeMatrix",
  916. X            "XbaeMatrix: Row or column parameter out of bounds for SetCell.",
  917. X            NULL, 0);
  918. X    return;
  919. X    }
  920. X
  921. X    /*
  922. X     * Store the new value in the cell.
  923. X     */
  924. X    XtFree((XtPointer)mw->matrix.cells[row][column]);
  925. X    mw->matrix.cells[row][column] = XtNewString(value);
  926. X
  927. X    /*
  928. X     * Draw the cell.
  929. X     */
  930. X    if (IsCellVisible(mw, row, column)) {
  931. X    ClearCell(mw, row, column);
  932. X    DrawCell(mw, row, column);
  933. X    }
  934. X
  935. X    /*
  936. X     * If we are editing this cell, load the textField too.
  937. X     * XXX there is a bug in XmTextFieldSetString in Motif 1.1.3
  938. X     *     it doesn't handle "" strings well.  Use SetValues instead.
  939. X     */
  940. X    if (XtIsManaged(TextChild(mw)) &&
  941. X        mw->matrix.current_row == row && mw->matrix.current_column == column) {
  942. X        if (value[0] == '\0')
  943. X            XtVaSetValues(TextChild(mw),
  944. X                          XmNvalue, value,
  945. X                          NULL);
  946. X        else
  947. X            XmTextFieldSetString(TextChild(mw), value);
  948. X    }
  949. }
  950. X
  951. /*
  952. X * Public interface to set_cell method
  953. X */
  954. void
  955. XXbaeMatrixSetCell(w, row, column, value)
  956. Widget w;
  957. int row, column;
  958. String value;
  959. {
  960. X    /*
  961. X     * Make sure w is a Matrix or a subclass
  962. X     */
  963. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  964. X
  965. X    /*
  966. X     * Call the set_cell method
  967. X     */
  968. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.set_cell)
  969. X    ((XbaeMatrixWidget)w, row, column, value);
  970. }
  971. X
  972. /*
  973. X * Matrix edit_cell method
  974. X */
  975. static void
  976. EditCell(mw, row, column)
  977. XXbaeMatrixWidget mw;
  978. int row, column;
  979. {
  980. X    Boolean edit = True;
  981. X    int x, y;
  982. X
  983. X    if (row >= mw->matrix.rows || row < 0 ||
  984. X    column >= mw->matrix.columns || column < 0) {
  985. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  986. X            "editCell", "badIndex", "XbaeMatrix",
  987. X            "XbaeMatrix: Row or column parameter out of bounds for EditCell.",
  988. X            NULL, 0);
  989. X    return;
  990. X    }
  991. X
  992. X    /*
  993. X     * Attempt to commit the edit in the current cell. Return if we fail.
  994. X     */
  995. X    if (!DoCommitEdit(mw))
  996. X    return;
  997. X
  998. X    /*
  999. X     * Scroll the cell onto the screen
  1000. X     */
  1001. X    MakeCellVisible(mw, row, column);
  1002. X
  1003. X    /*
  1004. X     * Fixed cells are not editable
  1005. X     */
  1006. X    if (IS_FIXED(mw, row, column))
  1007. X    return;
  1008. X
  1009. X    /*
  1010. X     * If we have an enterCellCallback, call it to see if the cell is
  1011. X     * editable.
  1012. X     */
  1013. X    if (mw->matrix.enter_cell_callback) {
  1014. X    XbaeMatrixEnterCellCallbackStruct call_data;
  1015. X
  1016. X    call_data.reason = XbaeEnterCellReason;
  1017. X    call_data.row = row;
  1018. X    call_data.column = column;
  1019. X    call_data.doit = True;
  1020. X    XtCallCallbackList((Widget)mw, mw->matrix.enter_cell_callback,
  1021. X               (XtPointer) &call_data);
  1022. X
  1023. X    edit = call_data.doit;
  1024. X    }
  1025. X
  1026. X    mw->matrix.current_row = row;
  1027. X    mw->matrix.current_column = column;
  1028. X
  1029. X    /*
  1030. X     * Unmap the textField to avoid flashing.
  1031. X     */
  1032. X    if (XtIsManaged(TextChild(mw)) && XtIsRealized(TextChild(mw)))
  1033. X    XtUnmapWidget(TextChild(mw));
  1034. X
  1035. X    /*
  1036. X     * Convert the row/column to an xy position and move the textField
  1037. X     * to this position. (the xy position will be relative to the Clip
  1038. X     * widget because only non-fixed cells are editable)
  1039. X     */
  1040. X    RowColToXY(mw, row, column, &x, &y);
  1041. X    XtMoveWidget(TextChild(mw), x, y);
  1042. X
  1043. #ifdef notdef
  1044. X    /*
  1045. X     * XXX Resetting the XmTextField foreground can cause a protocol error in
  1046. X     * XmTextField.  I filed a bug report.  Put this code back in when it
  1047. X     * is fixed.
  1048. X     */
  1049. X    /*
  1050. X     * Figure out what color the textField needs to be
  1051. X     */
  1052. X    if (mw->matrix.colors)
  1053. X    color = mw->matrix.colors[row][column];
  1054. X    else
  1055. X    color = mw->manager.foreground;
  1056. X
  1057. X    /*
  1058. X     * Include XmNforeground in the setvalues below
  1059. X     */
  1060. #endif
  1061. X
  1062. X    /*
  1063. X     * Setup the textField for the new cell. If the modifyVerify CB
  1064. X     * rejects the new value, then it is the applications fault for
  1065. X     * loading the cell with a bad value to begin with.
  1066. X     */
  1067. X    XtVaSetValues(TextChild(mw),
  1068. X          XmNvalue,    mw->matrix.cells[row][column],
  1069. X          XmNwidth,    COLUMN_WIDTH(mw, column),
  1070. X          XmNheight,    ROW_HEIGHT(mw),
  1071. X          XmNmaxLength, mw->matrix.column_max_lengths
  1072. X                ? mw->matrix.column_max_lengths[column]
  1073. X                : (int)mw->matrix.column_widths[column],
  1074. X          XmNeditable,    edit,
  1075. X          XmNcursorPositionVisible, edit,
  1076. X          NULL);
  1077. X
  1078. X    /*
  1079. X     * We need this to work around an XmTextField problem with
  1080. X     * the I-beam and caret
  1081. X     */
  1082. X    if (edit)
  1083. X    XmTextFieldSetInsertionPosition(TextChild(mw),
  1084. X                    strlen(mw->matrix.cells[row][column]));
  1085. X
  1086. X    /*
  1087. X     * Manage and map the textField
  1088. X     */
  1089. X    XtManageChild(TextChild(mw));
  1090. X    if (XtIsRealized(TextChild(mw)))
  1091. X    XtMapWidget(TextChild(mw));
  1092. }
  1093. X
  1094. /*
  1095. X * Public interface to edit_cell method
  1096. X */
  1097. void
  1098. XXbaeMatrixEditCell(w, row, column)
  1099. Widget w;
  1100. int row, column;
  1101. {
  1102. X    /*
  1103. X     * Make sure w is a Matrix or a subclass
  1104. X     */
  1105. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1106. X
  1107. X    /*
  1108. X     * Call the edit_cell method
  1109. X     */
  1110. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.edit_cell)
  1111. X    ((XbaeMatrixWidget)w, row, column);
  1112. X
  1113. X    XmProcessTraversal(TextChild(((XbaeMatrixWidget)w)), XmTRAVERSE_CURRENT);
  1114. }
  1115. X
  1116. /*
  1117. X * Matrix select_cell method
  1118. X */
  1119. static void
  1120. SelectCell(mw, row, column)
  1121. XXbaeMatrixWidget mw;
  1122. int row, column;
  1123. {
  1124. X    if (row >= mw->matrix.rows || row < 0 ||
  1125. X    column >= mw->matrix.columns || column < 0) {
  1126. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1127. X            "selectCell", "badIndex", "XbaeMatrix",
  1128. X            "XbaeMatrix: Row or column parameter out of bounds for SelectCell.",
  1129. X            NULL, 0);
  1130. X    return;
  1131. X    }
  1132. X
  1133. X    /*
  1134. X     * Scroll the cell onto the screen
  1135. X     */
  1136. X    MakeCellVisible(mw, row, column);
  1137. X
  1138. X    /*
  1139. X     * If the cell is not already selected, select it and redraw it
  1140. X     */
  1141. X    if (!mw->matrix.selected_cells[row][column]) {
  1142. X    mw->matrix.selected_cells[row][column] = True;
  1143. X    DrawCell(mw, row, column);
  1144. X    }
  1145. }
  1146. X
  1147. /*
  1148. X * Public interface to select_cell method
  1149. X */
  1150. void
  1151. XXbaeMatrixSelectCell(w, row, column)
  1152. Widget w;
  1153. int row, column;
  1154. {
  1155. X    /*
  1156. X     * Make sure w is a Matrix or a subclass
  1157. X     */
  1158. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1159. X
  1160. X    /*
  1161. X     * Call the select_cell method
  1162. X     */
  1163. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.select_cell)
  1164. X    ((XbaeMatrixWidget)w, row, column);
  1165. }
  1166. X
  1167. /*
  1168. X * Matrix select_row method
  1169. X */
  1170. static void
  1171. SelectRow(mw, row)
  1172. XXbaeMatrixWidget mw;
  1173. int row;
  1174. {
  1175. X    int j, lc, rc;
  1176. X
  1177. X    if (row >= mw->matrix.rows || row < 0) {
  1178. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1179. X            "selectRow", "badIndex", "XbaeMatrix",
  1180. X            "XbaeMatrix: Row out of bounds for SelectRow.",
  1181. X            NULL, 0);
  1182. X    return;
  1183. X    }
  1184. X
  1185. X    /*
  1186. X     * Scroll the row onto the screen
  1187. X     */
  1188. X    MakeRowVisible(mw, row);
  1189. X
  1190. X    /*
  1191. X     * For each cell in the row, if the cell is not already selected,
  1192. X     * select it and redraw it
  1193. X     */
  1194. X    GetVisibleColumns(mw, &lc, &rc);
  1195. X    for (j = 0; j < mw->matrix.columns; j++) {
  1196. X    if (!mw->matrix.selected_cells[row][j]) {
  1197. X        mw->matrix.selected_cells[row][j] = True;
  1198. X        if ((j >= lc && j <= rc) || j < mw->matrix.fixed_columns) {
  1199. X        ClearCell(mw, row, j);
  1200. X        DrawCell(mw, row, j);
  1201. X        }
  1202. X    }
  1203. X    }
  1204. }
  1205. X
  1206. /*
  1207. X * Public interface to select_row method
  1208. X */
  1209. void
  1210. XXbaeMatrixSelectRow(w, row)
  1211. Widget w;
  1212. int row;
  1213. {
  1214. X    /*
  1215. X     * Make sure w is a Matrix or a subclass
  1216. X     */
  1217. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1218. X
  1219. X    /*
  1220. X     * Call the select_row method
  1221. X     */
  1222. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.select_row)
  1223. X    ((XbaeMatrixWidget)w, row);
  1224. }
  1225. X
  1226. /*
  1227. X * Matrix select_column method
  1228. X */
  1229. static void
  1230. SelectColumn(mw, column)
  1231. XXbaeMatrixWidget mw;
  1232. int column;
  1233. {
  1234. X    int i, tr, br;
  1235. X
  1236. X    if (column >= mw->matrix.columns || column < 0) {
  1237. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1238. X            "selectColumn", "badIndex", "XbaeMatrix",
  1239. X            "XbaeMatrix: Column out of bounds for SelectColumn.",
  1240. X            NULL, 0);
  1241. X    return;
  1242. X    }
  1243. X
  1244. X    /*
  1245. X     * Scroll the column onto the screen
  1246. X     */
  1247. X    MakeColumnVisible(mw, column);
  1248. X
  1249. X    /*
  1250. X     * For each cell in the column, if the cell is not already selected,
  1251. X     * select it and redraw it
  1252. X     */
  1253. X    GetVisibleRows(mw, &tr, &br);
  1254. X    for (i = 0; i < mw->matrix.rows; i++) {
  1255. X    if (!mw->matrix.selected_cells[i][column]) {
  1256. X        mw->matrix.selected_cells[i][column] = True;
  1257. X        if ((i >= tr && i <= br) || i < mw->matrix.fixed_rows) {
  1258. X        ClearCell(mw, i, column);
  1259. X        DrawCell(mw, i, column);
  1260. X        }
  1261. X    }
  1262. X    }
  1263. }
  1264. X
  1265. /*
  1266. X * Public interface to select_column method
  1267. X */
  1268. void
  1269. XXbaeMatrixSelectColumn(w, column)
  1270. Widget w;
  1271. int column;
  1272. {
  1273. X    /*
  1274. X     * Make sure w is a Matrix or a subclass
  1275. X     */
  1276. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1277. X
  1278. X    /*
  1279. X     * Call the select_column method
  1280. X     */
  1281. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.select_column)
  1282. X    ((XbaeMatrixWidget)w, column);
  1283. }
  1284. X
  1285. /*
  1286. X * Matrix deselect_all method
  1287. X */
  1288. static void
  1289. DeselectAll(mw)
  1290. XXbaeMatrixWidget mw;
  1291. {
  1292. X    int i, j;
  1293. X    int tr, br, lc, rc;
  1294. X
  1295. X    GetVisibleCells(mw, &tr, &br, &lc, &rc);
  1296. X    for (i = 0; i < mw->matrix.rows; i++)
  1297. X    for (j = 0; j < mw->matrix.columns; j++) {
  1298. X        if (mw->matrix.selected_cells[i][j]) {
  1299. X        mw->matrix.selected_cells[i][j] = False;
  1300. X        if ((i >= tr && i <= br && j >= lc && j <= rc) ||
  1301. X            (i < mw->matrix.fixed_rows && j >= lc && j <= rc) ||
  1302. X            (j < mw->matrix.fixed_columns && i >= tr && i <= br)) {
  1303. X            ClearCell(mw, i, j);
  1304. X            DrawCell(mw, i, j);
  1305. X        }
  1306. X        }
  1307. X    }
  1308. }
  1309. X
  1310. /*
  1311. X * Public interface to deselect_all method
  1312. X */
  1313. void
  1314. XXbaeMatrixDeselectAll(w)
  1315. Widget w;
  1316. {
  1317. X    /*
  1318. X     * Make sure w is a Matrix or a subclass
  1319. X     */
  1320. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1321. X
  1322. X    /*
  1323. X     * Call the deselect_all method
  1324. X     */
  1325. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.deselect_all)
  1326. X    ((XbaeMatrixWidget)w);
  1327. }
  1328. X
  1329. /*
  1330. X * Matrix deselect_cell method
  1331. X */
  1332. static void
  1333. DeselectCell(mw, row, column)
  1334. XXbaeMatrixWidget mw;
  1335. int row;
  1336. int column;
  1337. {
  1338. X    if (row >= mw->matrix.rows || row < 0 ||
  1339. X    column > mw->matrix.columns - 1 || column < 0) {
  1340. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1341. X            "deselectCell", "badIndex", "XbaeMatrix",
  1342. X            "XbaeMatrix: Row or column parameter out of bounds for DeselectCell.",
  1343. X            NULL, 0);
  1344. X    return;
  1345. X    }
  1346. X
  1347. X    if (mw->matrix.selected_cells[row][column]) {
  1348. X    mw->matrix.selected_cells[row][column] = False;
  1349. X    if (IsCellVisible(mw, row, column)) {
  1350. X        ClearCell(mw, row, column);
  1351. X        DrawCell(mw, row, column);
  1352. X    }
  1353. X    }
  1354. }
  1355. X
  1356. /*
  1357. X * Public interface to deselect_cell method
  1358. X */
  1359. void
  1360. XXbaeMatrixDeselectCell(w, row, column)
  1361. Widget w;
  1362. int row;
  1363. int column;
  1364. {
  1365. X    /*
  1366. X     * Make sure w is a Matrix or a subclass
  1367. X     */
  1368. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1369. X
  1370. X    /*
  1371. X     * Call the deselect_cell method
  1372. X     */
  1373. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.deselect_cell)
  1374. X    ((XbaeMatrixWidget)w, row, column);
  1375. }
  1376. X
  1377. /*
  1378. X * Matrix deselect_row method
  1379. X */
  1380. static void
  1381. DeselectRow(mw, row)
  1382. XXbaeMatrixWidget mw;
  1383. int row;
  1384. {
  1385. X    int j, lc, rc;
  1386. X
  1387. X    if (row >= mw->matrix.rows || row < 0) {
  1388. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1389. X            "deselectRow", "badIndex", "XbaeMatrix",
  1390. X            "XbaeMatrix: Row parameter out of bounds for DeselectRow.",
  1391. X            NULL, 0);
  1392. X    return;
  1393. X    }
  1394. X
  1395. X    /*
  1396. X     * For each cell in the row, if the cell is selected,
  1397. X     * deselect it and redraw it
  1398. X     */
  1399. X    GetVisibleColumns(mw, &lc, &rc);
  1400. X    for (j = 0; j < mw->matrix.columns; j++) {
  1401. X    if (mw->matrix.selected_cells[row][j]) {
  1402. X        mw->matrix.selected_cells[row][j] = False;
  1403. X        if ((j >= lc && j <= rc) || j < mw->matrix.fixed_columns) {
  1404. X        ClearCell(mw, row, j);
  1405. X        DrawCell(mw, row, j);
  1406. X        }
  1407. X    }
  1408. X    }
  1409. }
  1410. X
  1411. /*
  1412. X * Public interface to deselect_row method
  1413. X */
  1414. void
  1415. XXbaeMatrixDeselectRow(w, row)
  1416. Widget w;
  1417. int row;
  1418. {
  1419. X    /*
  1420. X     * Make sure w is a Matrix or a subclass
  1421. X     */
  1422. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1423. X
  1424. X    /*
  1425. X     * Call the deselect_row method
  1426. X     */
  1427. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.deselect_row)
  1428. X    ((XbaeMatrixWidget)w, row);
  1429. }
  1430. X
  1431. /*
  1432. X * Matrix deselect_column method
  1433. X */
  1434. static void
  1435. DeselectColumn(mw, column)
  1436. XXbaeMatrixWidget mw;
  1437. int column;
  1438. {
  1439. X    int i, tr, br;
  1440. X
  1441. X    if (column >= mw->matrix.columns || column < 0) {
  1442. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1443. X            "deselectColumn", "badIndex", "XbaeMatrix",
  1444. X            "XbaeMatrix: Column parameter out of bounds for DeselectColumn.",
  1445. X            NULL, 0);
  1446. X    return;
  1447. X    }
  1448. X
  1449. X    /*
  1450. X     * For each cell in the column, if the cell is selected,
  1451. X     * deselect it and redraw it
  1452. X     */
  1453. X    GetVisibleRows(mw, &tr, &br);
  1454. X    for (i = 0; i < mw->matrix.rows; i++) {
  1455. X    if (mw->matrix.selected_cells[i][column]) {
  1456. X        mw->matrix.selected_cells[i][column] = False;
  1457. X        if ((i >= tr && i <= br) || i < mw->matrix.fixed_rows) {
  1458. X        ClearCell(mw, i, column);
  1459. X        DrawCell(mw, i, column);
  1460. X        }
  1461. X    }
  1462. X    }
  1463. }
  1464. X
  1465. /*
  1466. X * Public interface to deselect_column method
  1467. X */
  1468. void
  1469. XXbaeMatrixDeselectColumn(w, column)
  1470. Widget w;
  1471. int column;
  1472. {
  1473. X    /*
  1474. X     * Make sure w is a Matrix or a subclass
  1475. X     */
  1476. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1477. X
  1478. X    /*
  1479. X     * Call the deselect_column method
  1480. X     */
  1481. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.deselect_column)
  1482. X    ((XbaeMatrixWidget)w, column);
  1483. }
  1484. X
  1485. /*
  1486. X * Matrix get_cell method
  1487. X */
  1488. static String
  1489. GetCell(mw, row, column)
  1490. XXbaeMatrixWidget mw;
  1491. int row, column;
  1492. {
  1493. X    if (row >= mw->matrix.rows || row < 0 ||
  1494. X    column > mw->matrix.columns - 1 || column < 0) {
  1495. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1496. X            "getCell", "badIndex", "XbaeMatrix",
  1497. X            "XbaeMatrix: Row or column parameter out of bounds for GetCell.",
  1498. X            NULL, 0);
  1499. X    return(NULL);
  1500. X    }
  1501. X
  1502. X    return mw->matrix.cells[row][column];
  1503. }
  1504. X
  1505. /*
  1506. X * Public interface to get_cell method
  1507. X */
  1508. String
  1509. XXbaeMatrixGetCell(w, row, column)
  1510. Widget w;
  1511. int row, column;
  1512. {
  1513. X    /*
  1514. X     * Make sure w is a Matrix or a subclass
  1515. X     */
  1516. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1517. X
  1518. X    /*
  1519. X     * Call the get_cell method
  1520. X     */
  1521. X    return (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.get_cell)
  1522. X    ((XbaeMatrixWidget)w, row, column);
  1523. }
  1524. X
  1525. /*
  1526. X * Matrix commit_edit method
  1527. X */
  1528. static Boolean
  1529. CommitEdit(mw, unmap)
  1530. XXbaeMatrixWidget mw;
  1531. Boolean unmap;
  1532. {
  1533. X    Boolean commit;
  1534. X
  1535. X    if (!XtIsManaged(TextChild(mw)))
  1536. X    return True;
  1537. X
  1538. X    /*
  1539. X     * Attempt to commit the edit
  1540. X     */
  1541. X    commit = DoCommitEdit(mw);
  1542. X
  1543. X    /*
  1544. X     * If the commit succeeded and we are supposed to unmap the textField,
  1545. X     * then hide the textField and traverse out
  1546. X     */
  1547. X    if (commit && unmap) {
  1548. X    XtUnmanageChild(TextChild(mw));
  1549. X    XmProcessTraversal(TextChild(mw), XmTRAVERSE_RIGHT);
  1550. X    }
  1551. X
  1552. X    return commit;
  1553. }
  1554. X
  1555. /*
  1556. X * Public interface to commit_edit method
  1557. X */
  1558. Boolean
  1559. XXbaeMatrixCommitEdit(w, unmap)
  1560. Widget w;
  1561. Boolean unmap;
  1562. {
  1563. X    /*
  1564. X     * Make sure w is a Matrix or a subclass
  1565. X     */
  1566. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1567. X
  1568. X    /*
  1569. X     * Call the commit_edit method
  1570. X     */
  1571. X    return (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.commit_edit)
  1572. X    ((XbaeMatrixWidget)w, unmap);
  1573. }
  1574. X
  1575. /*
  1576. X * Matrix cancel_edit method
  1577. X */
  1578. static void
  1579. CancelEdit(mw, unmap)
  1580. XXbaeMatrixWidget mw;
  1581. Boolean unmap;
  1582. {
  1583. X    if (!XtIsManaged(TextChild(mw)))
  1584. X    return;
  1585. X
  1586. X    /*
  1587. X     * If unmap is set, hide the textField and traverse out.
  1588. X     */
  1589. X    if (unmap) {
  1590. X    XtUnmanageChild(TextChild(mw));
  1591. X    XmProcessTraversal(TextChild(mw), XmTRAVERSE_RIGHT);
  1592. X    }
  1593. X
  1594. X    /*
  1595. X     * Don't unmap, just restore original contents
  1596. X     */
  1597. X    else {
  1598. X    XtVaSetValues(TextChild(mw),
  1599. X              XmNvalue,    mw->matrix.cells[mw->matrix.current_row]
  1600. X                        [mw->matrix.current_column],
  1601. X              NULL);
  1602. X    }
  1603. }
  1604. X
  1605. /*
  1606. X * Public interface to cancel_edit method
  1607. X */
  1608. void
  1609. XXbaeMatrixCancelEdit(w, unmap)
  1610. Widget w;
  1611. Boolean unmap;
  1612. {
  1613. X    /*
  1614. X     * Make sure w is a Matrix or a subclass
  1615. X     */
  1616. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1617. X
  1618. X    /*
  1619. X     * Call the cancel_edit method
  1620. X     */
  1621. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.cancel_edit)
  1622. X    ((XbaeMatrixWidget)w, unmap);
  1623. }
  1624. X
  1625. /*
  1626. X * Matrix add_rows method
  1627. X */
  1628. static void
  1629. AddRows(mw, position, rows, labels, colors, num_rows)
  1630. XXbaeMatrixWidget mw;
  1631. int position;
  1632. String *rows;
  1633. String *labels;
  1634. Pixel *colors;
  1635. int num_rows;
  1636. {
  1637. X    /*
  1638. X     * Do some error checking.
  1639. X     */
  1640. X    if (num_rows <= 0)
  1641. X    return;
  1642. X    if (position < 0 || position > mw->matrix.rows) {
  1643. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1644. X            "addRows", "badPosition", "XbaeMatrix",
  1645. X            "XbaeMatrix: Position out of bounds in AddRows.",
  1646. X            NULL, 0);
  1647. X    return;
  1648. X    }
  1649. X
  1650. X    /*
  1651. X     * Add the new rows into the internal cells/labels data structure.
  1652. X     */
  1653. X    AddRowsToTable(mw, position, rows, labels, colors, num_rows);
  1654. X
  1655. X    /*
  1656. X     * Reconfig the VSB maximum.
  1657. X     */
  1658. X    XtVaSetValues(VertScrollChild(mw),
  1659. X          XmNmaximum,    mw->matrix.rows,
  1660. X          NULL);
  1661. X
  1662. X    /*
  1663. X     * Relayout.
  1664. X     */
  1665. X    Resize(mw);
  1666. X
  1667. X    /*
  1668. X     * Call our cancel_edit method since the rows shifted underneath us
  1669. X     */
  1670. X    (*((XbaeMatrixWidgetClass) XtClass(mw))->matrix_class.cancel_edit)
  1671. X    (mw, True);
  1672. X
  1673. X    /*
  1674. X     * Generate expose events on Matrix and Clip to force the
  1675. X     * new rows to be drawn.
  1676. X     */
  1677. X    XClearArea(XtDisplay(mw), XtWindow(mw),
  1678. X           0, 0,
  1679. X           0 /*Full Width*/, 0 /*Full Height*/,
  1680. X           True);
  1681. X    XbaeClipRedraw(ClipChild(mw));
  1682. }
  1683. X
  1684. /*
  1685. X * Public interface to add_rows method
  1686. X */
  1687. void
  1688. XXbaeMatrixAddRows(w, position, rows, labels, colors, num_rows)
  1689. Widget w;
  1690. int position;
  1691. String *rows;
  1692. String *labels;
  1693. Pixel *colors;
  1694. int num_rows;
  1695. {
  1696. X    /*
  1697. X     * Make sure w is a Matrix or a subclass
  1698. X     */
  1699. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1700. X
  1701. X    /*
  1702. X     * Call the add_rows method
  1703. X     */
  1704. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.add_rows)
  1705. X    ((XbaeMatrixWidget)w, position, rows, labels, colors, num_rows);
  1706. }
  1707. X
  1708. /*
  1709. X * Matrix delete_rows method
  1710. X */
  1711. static void
  1712. DeleteRows(mw, position, num_rows)
  1713. XXbaeMatrixWidget mw;
  1714. int position;
  1715. int num_rows;
  1716. {
  1717. X    /*
  1718. X     * Do some error checking.
  1719. X     */
  1720. X    if (num_rows <= 0)
  1721. X    return;
  1722. X    if (position < 0 || position + num_rows > mw->matrix.rows) {
  1723. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1724. X            "deleteRows", "badPosition", "XbaeMatrix",
  1725. X            "XbaeMatrix: Position out of bounds in DeleteRows.",
  1726. X            NULL, 0);
  1727. X    return;
  1728. X    }
  1729. X    if (num_rows >= mw->matrix.rows - mw->matrix.fixed_rows) {
  1730. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1731. X            "deleteRows", "tooMany", "XbaeMatrix",
  1732. X            "XbaeMatrix: Attempting to delete too many rows in DeleteRows.",
  1733. X            NULL, 0);
  1734. X    return;
  1735. X    }
  1736. X
  1737. X    /*
  1738. X     * Delete the new rows from the internal cells/labels data structure.
  1739. X     */
  1740. X    DeleteRowsFromTable(mw, position, num_rows);
  1741. X
  1742. X    /*
  1743. X     * Reconfig the VSB maximum. Reset the sliderSize to avoid warnings.
  1744. X     */
  1745. X    XtVaSetValues(VertScrollChild(mw),
  1746. X          XmNmaximum,    mw->matrix.rows,
  1747. X          XmNsliderSize,1,
  1748. X          NULL);
  1749. X
  1750. X    /*
  1751. X     * Relayout.
  1752. X     */
  1753. X    Resize(mw);
  1754. X
  1755. X    /*
  1756. X     * Call our cancel_edit method since the rows shifted underneath us
  1757. X     */
  1758. X    (*((XbaeMatrixWidgetClass) XtClass(mw))->matrix_class.cancel_edit)
  1759. X    (mw, True);
  1760. X
  1761. X     /*
  1762. X     * Generate expose events on Matrix and Clip to force the
  1763. X     * rows to be redrawn.
  1764. X     */
  1765. X    XClearArea(XtDisplay(mw), XtWindow(mw),
  1766. X           0, 0,
  1767. X           0 /*Full Width*/, 0 /*Full Height*/,
  1768. X           True);
  1769. X    XbaeClipRedraw(ClipChild(mw));
  1770. }
  1771. X
  1772. /*
  1773. X * Public interface to delete_rows method
  1774. X */
  1775. void
  1776. XXbaeMatrixDeleteRows(w, position, num_rows)
  1777. Widget w;
  1778. int position;
  1779. int num_rows;
  1780. {
  1781. X    /*
  1782. X     * Make sure w is a Matrix or a subclass
  1783. X     */
  1784. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1785. X
  1786. X    /*
  1787. X     * Call the delete_rows method
  1788. X     */
  1789. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.delete_rows)
  1790. X    ((XbaeMatrixWidget)w, position, num_rows);
  1791. }
  1792. X
  1793. /*
  1794. X * Matrix add_columns method.
  1795. X */
  1796. static void
  1797. AddColumns(mw, position, columns, labels, widths, max_lengths,
  1798. X       alignments, label_alignments, colors, num_columns)
  1799. XXbaeMatrixWidget mw;
  1800. int position;
  1801. String *columns;
  1802. String *labels;
  1803. short *widths;
  1804. int *max_lengths;
  1805. unsigned char *alignments;
  1806. unsigned char *label_alignments;
  1807. Pixel *colors;
  1808. int num_columns;
  1809. {
  1810. X    /*
  1811. X     * Do some error checking.
  1812. X     */
  1813. X    if (num_columns <= 0)
  1814. X    return;
  1815. X    if (position < 0 || position > mw->matrix.columns) {
  1816. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1817. X            "addColumns", "badPosition", "XbaeMatrix",
  1818. X            "XbaeMatrix: Position out of bounds in AddColumns.",
  1819. X            NULL, 0);
  1820. X    return;
  1821. X    }
  1822. X    if (!widths) {
  1823. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1824. X            "addColumns", "noWidths", "XbaeMatrix",
  1825. X            "XbaeMatrix: Must specify column widths in AddColumns.",
  1826. X            NULL, 0);
  1827. X    return;
  1828. X    }
  1829. X
  1830. X    /*
  1831. X     * Add the new rows into the internal cells/labels data structure.
  1832. X     */
  1833. X    AddColumnsToTable(mw, position, columns, labels, widths, max_lengths,
  1834. X              alignments, label_alignments, colors, num_columns);
  1835. X
  1836. X    /*
  1837. X     * Reconfig the HSB maximum.
  1838. X     */
  1839. X    XtVaSetValues(HorizScrollChild(mw),
  1840. X          XmNmaximum,    mw->matrix.cell_total_width,
  1841. X          NULL);
  1842. X
  1843. X    /*
  1844. X     * Relayout.
  1845. X     */
  1846. X    Resize(mw);
  1847. X
  1848. X    /*
  1849. X     * Call our cancel_edit method since the columns shifted underneath us
  1850. X     */
  1851. X    (*((XbaeMatrixWidgetClass) XtClass(mw))->matrix_class.cancel_edit)
  1852. X    (mw, True);
  1853. X
  1854. X    /*
  1855. X     * Generate expose events on Matrix and Clip to force the
  1856. X     * new columns to be drawn.
  1857. X     */
  1858. X    XClearArea(XtDisplay(mw), XtWindow(mw),
  1859. X           0, 0,
  1860. X           0 /*Full Width*/, 0 /*Full Height*/,
  1861. X           True);
  1862. X    XbaeClipRedraw(ClipChild(mw));
  1863. }
  1864. X
  1865. /*
  1866. X * Public interface to add_columns method
  1867. X */
  1868. void
  1869. XXbaeMatrixAddColumns(w, position, columns, labels, widths, max_lengths,
  1870. X              alignments, label_alignments, colors, num_columns) 
  1871. Widget w;
  1872. int position;
  1873. String *columns;
  1874. String *labels;
  1875. short *widths;
  1876. int *max_lengths;
  1877. unsigned char *alignments;
  1878. unsigned char *label_alignments;
  1879. Pixel *colors;
  1880. int num_columns;
  1881. {
  1882. X    /*
  1883. X     * Make sure w is a Matrix or a subclass
  1884. X     */
  1885. X    XtCheckSubclass(w, xbaeMatrixWidgetClass, NULL);
  1886. X
  1887. X    /*
  1888. X     * Call the add_columns method
  1889. X     */
  1890. X    (*((XbaeMatrixWidgetClass) XtClass(w))->matrix_class.add_columns)
  1891. X    ((XbaeMatrixWidget)w, position, columns, labels, widths,
  1892. X     max_lengths, alignments, label_alignments, colors, num_columns);
  1893. }
  1894. X
  1895. /*
  1896. X * Matrix delete_columns method
  1897. X */
  1898. static void
  1899. DeleteColumns(mw, position, num_columns)
  1900. XXbaeMatrixWidget mw;
  1901. int position;
  1902. int num_columns;
  1903. {
  1904. X    /*
  1905. X     * Do some error checking.
  1906. X     */
  1907. X    if (num_columns <= 0)
  1908. X    return;
  1909. X    if (position < 0 || position + num_columns > mw->matrix.columns) {
  1910. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1911. X            "deleteColumns", "badPosition", "XbaeMatrix",
  1912. X            "XbaeMatrix: Position out of bounds in DeleteColumns.",
  1913. X            NULL, 0);
  1914. X    return;
  1915. X    }
  1916. X    if (num_columns >= mw->matrix.columns - mw->matrix.fixed_columns) {
  1917. X    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)mw),
  1918. X            "deleteColumns", "tooMany", "XbaeMatrix",
  1919. X            "XbaeMatrix: Attempting to delete too many columns in DeleteColumns.",
  1920. X            NULL, 0);
  1921. X    return;
  1922. X    }
  1923. X
  1924. X    /*
  1925. X     * Delete the new columns from the internal cells/labels data structure.
  1926. X     */
  1927. X    DeleteColumnsFromTable(mw, position, num_columns);
  1928. X
  1929. X    /*
  1930. X     * Reconfig the HSB maximum. Reset the sliderSize to avoid warnings.
  1931. X     */
  1932. X    XtVaSetValues(HorizScrollChild(mw),
  1933. X          XmNmaximum,    mw->matrix.cell_total_width,
  1934. X          XmNsliderSize,1,
  1935. X          NULL);
  1936. X
  1937. X    /*
  1938. X     * Relayout.
  1939. X     */
  1940. X    Resize(mw);
  1941. X
  1942. X    /*
  1943. X     * Call our cancel_edit method since the columns shifted underneath us
  1944. SHAR_EOF
  1945. true || echo 'restore of Xbae/src/Matrix.c failed'
  1946. fi
  1947. echo 'End of Xbae part 8'
  1948. echo 'File Xbae/src/Matrix.c is continued in part 9'
  1949. echo 9 > _shar_seq_.tmp
  1950. exit 0
  1951. -- 
  1952. --
  1953. Molecular Simulations, Inc.            mail: dcmartin@msi.com
  1954. 796 N. Pastoria Avenue                uucp: uunet!dcmartin
  1955. Sunnyvale, California 94086            at&t: 408/522-9236
  1956.